From 3a35139a3212d4d07da3c0f391b00f2e1daa2fa3 Mon Sep 17 00:00:00 2001 From: Moises Silva Date: Tue, 31 Aug 2010 18:13:56 -0400 Subject: [PATCH 01/10] freetdm: add asynchronous signal notification --- libs/freetdm/src/ftdm_io.c | 52 ++++++++++++++++--- libs/freetdm/src/include/freetdm.h | 35 +++++++------ libs/freetdm/src/include/private/ftdm_core.h | 3 ++ libs/freetdm/src/include/private/ftdm_types.h | 4 ++ 4 files changed, 70 insertions(+), 24 deletions(-) diff --git a/libs/freetdm/src/ftdm_io.c b/libs/freetdm/src/ftdm_io.c index 238a9fc060..c53e9aa1fb 100644 --- a/libs/freetdm/src/ftdm_io.c +++ b/libs/freetdm/src/ftdm_io.c @@ -51,6 +51,7 @@ #include "ftdm_cpu_monitor.h" #define SPAN_PENDING_CHANS_QUEUE_SIZE 1000 +#define SPAN_PENDING_SIGNALS_QUEUE_SIZE 1000 #define FTDM_READ_TRACE_INDEX 0 #define FTDM_WRITE_TRACE_INDEX 1 @@ -463,6 +464,9 @@ static ftdm_status_t ftdm_span_destroy(ftdm_span_t *span) if (span->pendingchans) { ftdm_queue_destroy(&span->pendingchans); } + if (span->pendingsignals) { + ftdm_queue_destroy(&span->pendingsignals); + } ftdm_mutex_unlock(span->mutex); ftdm_mutex_destroy(&span->mutex); ftdm_safe_free(span->signal_data); @@ -4097,6 +4101,9 @@ static ftdm_status_t post_configure_span_channels(ftdm_span_t *span) if (ftdm_test_flag(span, FTDM_SPAN_USE_CHAN_QUEUE)) { status = ftdm_queue_create(&span->pendingchans, SPAN_PENDING_CHANS_QUEUE_SIZE); } + if (status == FTDM_SUCCESS && ftdm_test_flag(span, FTDM_SPAN_USE_SIGNALS_QUEUE)) { + status = ftdm_queue_create(&span->pendingsignals, SPAN_PENDING_SIGNALS_QUEUE_SIZE); + } return status; } @@ -4362,10 +4369,39 @@ FT_DECLARE(ftdm_status_t) ftdm_group_create(ftdm_group_t **group, const char *na return status; } +static ftdm_status_t ftdm_span_trigger_signal(const ftdm_span_t *span, ftdm_sigmsg_t *sigmsg) +{ + return span->signal_cb(sigmsg); +} + +static ftdm_status_t ftdm_span_queue_signal(const ftdm_span_t *span, ftdm_sigmsg_t *sigmsg) +{ + ftdm_sigmsg_t *new_sigmsg = NULL; + + ftdm_assert_return((sigmsg->raw_data == NULL), FTDM_FAIL, "No raw data should be used with asynchronous notification\n"); + + new_sigmsg = ftdm_calloc(1, sizeof(*sigmsg)); + if (!new_sigmsg) { + return FTDM_FAIL; + } + memcpy(new_sigmsg, sigmsg, sizeof(*sigmsg)); + + ftdm_queue_enqueue(span->pendingsignals, new_sigmsg); + return FTDM_SUCCESS; +} + +FT_DECLARE(ftdm_status_t) ftdm_span_trigger_signals(const ftdm_span_t *span) +{ + ftdm_sigmsg_t *sigmsg = NULL; + while ((sigmsg = ftdm_queue_dequeue(span->pendingsignals))) { + ftdm_span_trigger_signal(span, sigmsg); + ftdm_safe_free(sigmsg); + } + return FTDM_SUCCESS; +} + FT_DECLARE(ftdm_status_t) ftdm_span_send_signal(ftdm_span_t *span, ftdm_sigmsg_t *sigmsg) { - ftdm_status_t status = FTDM_FAIL; - if (sigmsg->channel) { ftdm_mutex_lock(sigmsg->channel->mutex); } @@ -4400,10 +4436,12 @@ FT_DECLARE(ftdm_status_t) ftdm_span_send_signal(ftdm_span_t *span, ftdm_sigmsg_t break; } - - /* call the user callback only if set */ - if (span->signal_cb) { - status = span->signal_cb(sigmsg); + + /* if the signaling module uses a queue for signaling notifications, then enqueue it */ + if (ftdm_test_flag(span, FTDM_SPAN_USE_SIGNALS_QUEUE)) { + ftdm_span_queue_signal(span, sigmsg); + } else { + ftdm_span_trigger_signal(span, sigmsg); } done: @@ -4411,7 +4449,7 @@ done: ftdm_mutex_unlock(sigmsg->channel->mutex); } - return status; + return FTDM_SUCCESS; } static void *ftdm_cpu_monitor_run(ftdm_thread_t *me, void *obj) diff --git a/libs/freetdm/src/include/freetdm.h b/libs/freetdm/src/include/freetdm.h index af55370338..b72aeb619a 100644 --- a/libs/freetdm/src/include/freetdm.h +++ b/libs/freetdm/src/include/freetdm.h @@ -317,23 +317,6 @@ typedef struct ftdm_channel_config { float txgain; } ftdm_channel_config_t; -/*! \brief Generic signaling message */ -struct ftdm_sigmsg { - ftdm_signal_event_t event_id; /*!< The type of message */ - ftdm_channel_t *channel; /*!< Related channel */ - uint32_t chan_id; /*!< easy access to chan id */ - uint32_t span_id; /*!< easy access to span_id */ - void *raw_data; /*!< Message specific data if any */ - uint32_t raw_data_len; /*!< Data len in case is needed */ -}; - -/*! \brief Crash policy - * Useful for debugging only, default policy is never, if you wish to crash on asserts then use ftdm_global_set_crash_policy */ -typedef enum { - FTDM_CRASH_NEVER = 0, - FTDM_CRASH_ON_ASSERT -} ftdm_crash_policy_t; - /*! \brief Signaling status on a given span or specific channel on protocols that support it */ @@ -352,6 +335,24 @@ typedef enum { /*! \brief Move from string to ftdm_signaling_status_t and viceversa */ FTDM_STR2ENUM_P(ftdm_str2ftdm_signaling_status, ftdm_signaling_status2str, ftdm_signaling_status_t) +/*! \brief Generic signaling message */ +struct ftdm_sigmsg { + ftdm_signal_event_t event_id; /*!< The type of message */ + ftdm_channel_t *channel; /*!< Related channel */ + uint32_t chan_id; /*!< easy access to chan id */ + uint32_t span_id; /*!< easy access to span_id */ + ftdm_signaling_status_t sigstatus; /*!< Signaling status (valid if event_id is FTDM_SIGEVENT_SIGSTATUS_CHANGED) */ + void *raw_data; /*!< Message specific data if any */ + uint32_t raw_data_len; /*!< Data len in case is needed */ +}; + +/*! \brief Crash policy + * Useful for debugging only, default policy is never, if you wish to crash on asserts then use ftdm_global_set_crash_policy */ +typedef enum { + FTDM_CRASH_NEVER = 0, + FTDM_CRASH_ON_ASSERT +} ftdm_crash_policy_t; + /*! \brief I/O waiting flags */ typedef enum { FTDM_NO_FLAGS = 0, diff --git a/libs/freetdm/src/include/private/ftdm_core.h b/libs/freetdm/src/include/private/ftdm_core.h index 95f34b4dd2..74bea8148c 100644 --- a/libs/freetdm/src/include/private/ftdm_core.h +++ b/libs/freetdm/src/include/private/ftdm_core.h @@ -466,6 +466,7 @@ struct ftdm_span { ftdm_state_map_t *state_map; ftdm_caller_data_t default_caller_data; ftdm_queue_t *pendingchans; + ftdm_queue_t *pendingsignals; struct ftdm_span *next; }; @@ -579,6 +580,8 @@ FT_DECLARE(ftdm_status_t) ftdm_span_next_event(ftdm_span_t *span, ftdm_event_t * */ FT_DECLARE(ftdm_status_t) ftdm_channel_queue_dtmf(ftdm_channel_t *ftdmchan, const char *dtmf); +/* dequeue pending signals and notify the user via the span signal callback */ +FT_DECLARE(ftdm_status_t) ftdm_span_trigger_signals(const ftdm_span_t *span); /*! \brief Assert condition diff --git a/libs/freetdm/src/include/private/ftdm_types.h b/libs/freetdm/src/include/private/ftdm_types.h index 572e63299b..d8e8b5c2e6 100644 --- a/libs/freetdm/src/include/private/ftdm_types.h +++ b/libs/freetdm/src/include/private/ftdm_types.h @@ -176,6 +176,10 @@ typedef enum { FTDM_SPAN_USE_CHAN_QUEUE = (1 << 6), FTDM_SPAN_SUGGEST_CHAN_ID = (1 << 7), FTDM_SPAN_USE_AV_RATE = (1 << 8), + /* If you use this flag, you MUST call ftdm_span_trigger_signals to deliver the user signals + * after having called ftdm_send_span_signal(), which with this flag it will just enqueue the signal + * for later delivery */ + FTDM_SPAN_USE_SIGNALS_QUEUE = (1 << 9), } ftdm_span_flag_t; /*! \brief Channel supported features */ From e90ccb151e336e50a7083bd5e6d35e82128151a9 Mon Sep 17 00:00:00 2001 From: David Yat Sin Date: Tue, 31 Aug 2010 19:05:37 -0400 Subject: [PATCH 02/10] fix for segfaults in cases where we were still using raw_data as pointer --- libs/freetdm/mod_freetdm/mod_freetdm.c | 6 +++--- libs/freetdm/src/ftdm_io.c | 11 +++++++---- .../src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn.c | 5 +++-- .../ftmod_sangoma_isdn/ftmod_sangoma_isdn_cntrl.c | 2 +- 4 files changed, 14 insertions(+), 10 deletions(-) diff --git a/libs/freetdm/mod_freetdm/mod_freetdm.c b/libs/freetdm/mod_freetdm/mod_freetdm.c index 890d9d9d43..50eb7a2c4d 100755 --- a/libs/freetdm/mod_freetdm/mod_freetdm.c +++ b/libs/freetdm/mod_freetdm/mod_freetdm.c @@ -2107,10 +2107,10 @@ static FIO_SIGNAL_CB_FUNCTION(on_clear_channel_signal) } break; case FTDM_SIGEVENT_SIGSTATUS_CHANGED: - { - ftdm_signaling_status_t *sigstatus = (ftdm_signaling_status_t*)(sigmsg->raw_data); + { + ftdm_signaling_status_t sigstatus = sigmsg->raw_data ? *((ftdm_signaling_status_t*)(sigmsg->raw_data)) : sigmsg->sigstatus; switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "%d:%d signalling changed to :%s\n", - spanid, chanid, ftdm_signaling_status2str(*sigstatus)); + spanid, chanid, ftdm_signaling_status2str(sigstatus)); } break; default: diff --git a/libs/freetdm/src/ftdm_io.c b/libs/freetdm/src/ftdm_io.c index c53e9aa1fb..39eba67e8b 100644 --- a/libs/freetdm/src/ftdm_io.c +++ b/libs/freetdm/src/ftdm_io.c @@ -4410,10 +4410,13 @@ FT_DECLARE(ftdm_status_t) ftdm_span_send_signal(ftdm_span_t *span, ftdm_sigmsg_t switch (sigmsg->event_id) { case FTDM_SIGEVENT_SIGSTATUS_CHANGED: - if (*((ftdm_signaling_status_t*)(sigmsg->raw_data)) == FTDM_SIG_STATE_UP) { - ftdm_set_flag(sigmsg->channel, FTDM_CHANNEL_SIG_UP); - } else { - ftdm_clear_flag(sigmsg->channel, FTDM_CHANNEL_SIG_UP); + { + ftdm_signaling_status_t sigstatus = ftdm_test_flag(span, FTDM_SPAN_USE_SIGNALS_QUEUE) ? sigmsg->sigstatus : *((ftdm_signaling_status_t*)(sigmsg->raw_data)); + if (sigstatus == FTDM_SIG_STATE_UP) { + ftdm_set_flag(sigmsg->channel, FTDM_CHANNEL_SIG_UP); + } else { + ftdm_clear_flag(sigmsg->channel, FTDM_CHANNEL_SIG_UP); + } } break; diff --git a/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn.c b/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn.c index b47660b076..12a98f979b 100644 --- a/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn.c +++ b/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn.c @@ -279,11 +279,11 @@ static void *ftdm_sangoma_isdn_run(ftdm_thread_t *me, void *obj) ftdm_channel_unlock(ftdmchan); } - /* Check if there are any timers to process */ while ((sngisdn_event = ftdm_queue_dequeue(signal_data->event_queue))) { ftdm_sangoma_isdn_process_stack_event(span, sngisdn_event); ftdm_safe_free(sngisdn_event); - } + } + ftdm_span_trigger_signals(span); break; case FTDM_TIMEOUT: /* twiddle */ @@ -791,6 +791,7 @@ static FIO_CONFIGURE_SPAN_SIGNALING_FUNCTION(ftdm_sangoma_isdn_span_config) span->set_channel_sig_status = ftdm_sangoma_isdn_set_sig_status; span->state_map = &sangoma_isdn_state_map; ftdm_set_flag(span, FTDM_SPAN_USE_CHAN_QUEUE); + ftdm_set_flag(span, FTDM_SPAN_USE_SIGNALS_QUEUE); if (span->trunk_type == FTDM_TRUNK_BRI_PTMP || span->trunk_type == FTDM_TRUNK_BRI) { diff --git a/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_cntrl.c b/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_cntrl.c index 5299c91b44..7aba6a66ce 100644 --- a/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_cntrl.c +++ b/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_cntrl.c @@ -48,7 +48,7 @@ void sngisdn_set_chan_sig_status(ftdm_channel_t *ftdmchan, ftdm_signaling_status sig.span_id = ftdmchan->span_id; sig.channel = ftdmchan; sig.event_id = FTDM_SIGEVENT_SIGSTATUS_CHANGED; - sig.raw_data = &status; + sig.sigstatus = status; ftdm_span_send_signal(ftdmchan->span, &sig); return; } From b7c23acd40b6f69a2aca4d564cea9468c5cf2052 Mon Sep 17 00:00:00 2001 From: David Yat Sin Date: Tue, 31 Aug 2010 19:19:55 -0400 Subject: [PATCH 03/10] Removed DEBUG_CHAN_MEMORY --- .../freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn.c b/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn.c index 12a98f979b..61400ba825 100644 --- a/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn.c +++ b/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn.c @@ -35,7 +35,11 @@ #include "ftmod_sangoma_isdn.h" +#if 1 +#undef FTDM_DEBUG_CHAN_MEMORY +#else #define FTDM_DEBUG_CHAN_MEMORY +#endif #ifdef FTDM_DEBUG_CHAN_MEMORY #include From 65ce3554c8fcc0d75b0472470b3fd8dab58853b1 Mon Sep 17 00:00:00 2001 From: Moises Silva Date: Wed, 1 Sep 2010 11:21:29 -0400 Subject: [PATCH 04/10] freetdm: added proper bearer capability and user layer 1 protocol types --- libs/freetdm/src/include/freetdm.h | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/libs/freetdm/src/include/freetdm.h b/libs/freetdm/src/include/freetdm.h index b72aeb619a..c1e50ecb67 100644 --- a/libs/freetdm/src/include/freetdm.h +++ b/libs/freetdm/src/include/freetdm.h @@ -239,6 +239,20 @@ typedef struct { uint8_t plan; } ftdm_number_t; +/*! \brief bearer capability */ +typedef enum { + FTDM_BEARER_CAP_SPEECH = 0x00, + FTDM_BEARER_CAP_64K_UNRESTRICTED = 0x02, + FTDM_BEARER_CAP_3_1KHZ_AUDIO = 0x03 +} ftdm_bearer_cap_t; + +/*! \brief user information layer 1 protocol */ +typedef enum { + FTDM_USER_LAYER1_PROT_V110 = 0x01, + FTDM_USER_LAYER1_PROT_ULAW = 0x02, + FTDM_USER_LAYER1_PROT_ALAW = 0x03, +} ftdm_user_layer1_prot_t; + /*! \brief Caller information */ typedef struct ftdm_caller_data { char cid_date[8]; /*!< Caller ID date */ @@ -256,9 +270,9 @@ typedef struct ftdm_caller_data { uint32_t raw_data_len; /* !< Raw data length */ /* these 2 are undocumented right now, only used by boost: */ /* bearer capability */ - uint8_t bearer_capability; + ftdm_bearer_cap_t bearer_capability; /* user information layer 1 protocol */ - uint8_t bearer_layer1; + ftdm_user_layer1_prot_t bearer_layer1; } ftdm_caller_data_t; /*! \brief Tone type */ From e3b9db88947df3ae21ca1e20b24d84d230bb059a Mon Sep 17 00:00:00 2001 From: Konrad Hammel Date: Tue, 31 Aug 2010 17:33:42 -0400 Subject: [PATCH 05/10] freetdm: implemented Trillium stack message queueing --- libs/freetdm/Makefile.am | 25 +- .../ftmod_sangoma_ss7_handle.c | 1930 +++++++++++++++++ .../ftmod_sangoma_ss7/ftmod_sangoma_ss7_in.c | 1906 ++-------------- .../ftmod_sangoma_ss7_main.c | 169 +- .../ftmod_sangoma_ss7_main.h | 75 +- 5 files changed, 2341 insertions(+), 1764 deletions(-) create mode 100644 libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_handle.c diff --git a/libs/freetdm/Makefile.am b/libs/freetdm/Makefile.am index 6ccc473ce3..33a8b96936 100644 --- a/libs/freetdm/Makefile.am +++ b/libs/freetdm/Makefile.am @@ -268,18 +268,19 @@ ftmod_pritap_la_LIBADD = $(MYLIB) endif if SNGSS7 -ftmod_sangoma_ss7_la_SOURCES = $(SRC)/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_support.c \ - $(SRC)/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_main.c \ - $(SRC)/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_in.c \ - $(SRC)/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_out.c \ - $(SRC)/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_cntrl.c \ - $(SRC)/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_xml.c \ - $(SRC)/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_timers.c \ - $(SRC)/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_cli.c \ - $(SRC)/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_cfg.c \ - $(SRC)/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_sta.c \ - $(SRC)/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_sts.c \ - $(SRC)/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_logger.c +ftmod_sangoma_ss7_la_SOURCES = $(SRC)/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_support.c \ + $(SRC)/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_main.c \ + $(SRC)/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_handle.c \ + $(SRC)/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_in.c \ + $(SRC)/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_out.c \ + $(SRC)/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_cntrl.c \ + $(SRC)/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_xml.c \ + $(SRC)/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_timers.c \ + $(SRC)/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_cli.c \ + $(SRC)/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_cfg.c \ + $(SRC)/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_sta.c \ + $(SRC)/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_sts.c \ + $(SRC)/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_logger.c ftmod_sangoma_ss7_la_CFLAGS = $(AM_CFLAGS) $(MY_CFLAGS) -D_GNU_SOURCE ftmod_sangoma_ss7_la_LDFLAGS = -module -avoid-version -lsng_ss7 ftmod_sangoma_ss7_la_LIBADD = $(MYLIB) diff --git a/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_handle.c b/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_handle.c new file mode 100644 index 0000000000..d1f3a8b89c --- /dev/null +++ b/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_handle.c @@ -0,0 +1,1930 @@ +/* + * Copyright (c) 2009 Konrad Hammel + * All rights reserved. + * + * Redistribution and use in source and binary forms|with or without + * modification|are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice|this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice|this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * * Neither the name of the original author; nor the names of any contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES|INCLUDING|BUT NOT + * LIMITED TO|THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER + * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT|INDIRECT|INCIDENTAL|SPECIAL, + * EXEMPLARY|OR CONSEQUENTIAL DAMAGES (INCLUDING|BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE|DATA|OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY|WHETHER IN CONTRACT|STRICT LIABILITY|OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE|EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/* INCLUDE ********************************************************************/ +#include "ftmod_sangoma_ss7_main.h" +/******************************************************************************/ + +/* DEFINES ********************************************************************/ +/******************************************************************************/ + +/* GLOBALS ********************************************************************/ +/******************************************************************************/ + +/* PROTOTYPES *****************************************************************/ +/* PROTOTYPES *****************************************************************/ +ftdm_status_t handle_con_ind(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, SiConEvnt *siConEvnt); +ftdm_status_t handle_con_sta(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, SiCnStEvnt *siCnStEvnt, uint8_t evntType); +ftdm_status_t handle_con_cfm(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, SiConEvnt *siConEvnt); +ftdm_status_t handle_rel_ind(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, SiRelEvnt *siRelEvnt); +ftdm_status_t handle_rel_cfm(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, SiRelEvnt *siRelEvnt); +ftdm_status_t handle_dat_ind(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, SiInfoEvnt *siInfoEvnt); +ftdm_status_t handle_fac_ind(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, uint8_t evntType, SiFacEvnt *siFacEvnt); +ftdm_status_t handle_fac_cfm(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, uint8_t evntType, SiFacEvnt *siFacEvnt); +ftdm_status_t handle_umsg_ind(uint32_t suInstId, uint32_t spInstId, uint32_t circuit); +ftdm_status_t handle_sta_ind(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, uint8_t globalFlg, uint8_t evntType, SiStaEvnt *siStaEvnt); + +ftdm_status_t handle_reattempt(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, uint8_t globalFlg, uint8_t evntType, SiStaEvnt *siStaEvnt); +ftdm_status_t handle_pause(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, uint8_t globalFlg, uint8_t evntType, SiStaEvnt *siStaEvnt); +ftdm_status_t handle_resume(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, uint8_t globalFlg, uint8_t evntType, SiStaEvnt *siStaEvnt); +ftdm_status_t handle_cot_start(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, uint8_t globalFlg, uint8_t evntType, SiStaEvnt *siStaEvnt); +ftdm_status_t handle_cot_stop(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, uint8_t globalFlg, uint8_t evntType, SiStaEvnt *siStaEvnt); +ftdm_status_t handle_cot(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, uint8_t globalFlg, uint8_t evntType, SiStaEvnt *siStaEvnt); +ftdm_status_t handle_rsc_req(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, uint8_t globalFlg, uint8_t evntType, SiStaEvnt *siStaEvnt); +ftdm_status_t handle_local_rsc_req(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, uint8_t globalFlg, uint8_t evntType, SiStaEvnt *siStaEvnt); +ftdm_status_t handle_rsc_rsp(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, uint8_t globalFlg, uint8_t evntType, SiStaEvnt *siStaEvnt); +ftdm_status_t handle_grs_req(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, uint8_t globalFlg, uint8_t evntType, SiStaEvnt *siStaEvnt); +ftdm_status_t handle_grs_rsp(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, uint8_t globalFlg, uint8_t evntType, SiStaEvnt *siStaEvnt); +ftdm_status_t handle_blo_req(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, uint8_t globalFlg, uint8_t evntType, SiStaEvnt *siStaEvnt); +ftdm_status_t handle_blo_rsp(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, uint8_t globalFlg, uint8_t evntType, SiStaEvnt *siStaEvnt); +ftdm_status_t handle_ubl_req(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, uint8_t globalFlg, uint8_t evntType, SiStaEvnt *siStaEvnt); +ftdm_status_t handle_ubl_rsp(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, uint8_t globalFlg, uint8_t evntType, SiStaEvnt *siStaEvnt); +ftdm_status_t handle_local_blk(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, uint8_t globalFlg, uint8_t evntType, SiStaEvnt *siStaEvnt); +ftdm_status_t handle_local_ubl(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, uint8_t globalFlg, uint8_t evntType, SiStaEvnt *siStaEvnt); +ftdm_status_t handle_ucic(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, uint8_t globalFlg, uint8_t evntType, SiStaEvnt *siStaEvnt); +/******************************************************************************/ + +/* FUNCTIONS ******************************************************************/ +ftdm_status_t handle_con_ind(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, SiConEvnt *siConEvnt) +{ + SS7_FUNC_TRACE_ENTER(__FUNCTION__); + + sngss7_chan_data_t *sngss7_info ; + ftdm_channel_t *ftdmchan; + + /* get the ftdmchan and ss7_chan_data from the circuit */ + if (extract_chan_data(circuit, &sngss7_info, &ftdmchan)) { + SS7_ERROR("Failed to extract channel data for circuit = %d!\n", circuit); + SS7_FUNC_TRACE_EXIT(__FUNCTION__); + return FTDM_FAIL; + } + + /* now that we have the right channel...put a lock on it so no-one else can use it */ + ftdm_mutex_lock(ftdmchan->mutex); + + /* check if there is a pending state change, give it a bit to clear */ + if (check_for_state_change(ftdmchan)) { + SS7_ERROR("Failed to wait for pending state change on CIC = %d\n", sngss7_info->circuit->cic); + ftdm_mutex_unlock(ftdmchan->mutex); + SS7_FUNC_TRACE_EXIT(__FUNCTION__); + SS7_ASSERT; + }; + + SS7_MSG_TRACE(ftdmchan, sngss7_info, "Rx IAM\n"); + + /* check if the circuit has a remote block */ + if ((sngss7_test_flag(sngss7_info, FLAG_CKT_MN_BLOCK_RX)) || + (sngss7_test_flag(sngss7_info, FLAG_GRP_HW_BLOCK_RX)) || + (sngss7_test_flag(sngss7_info, FLAG_GRP_MN_BLOCK_RX))) { + + /* as per Q.764, 2.8.2.3 xiv ... remove the block from this channel */ + sngss7_clear_flag(sngss7_info, FLAG_CKT_MN_BLOCK_RX); + sngss7_clear_flag(sngss7_info, FLAG_GRP_HW_BLOCK_RX); + sngss7_clear_flag(sngss7_info, FLAG_GRP_MN_BLOCK_RX); + + /* KONRAD FIX ME : check in case there is a ckt and grp block */ + } + + /* check whether the ftdm channel is in a state to accept a call */ + switch (ftdmchan->state) { + /**************************************************************************/ + case (FTDM_CHANNEL_STATE_DOWN): /* only state it is fully valid to get IAM */ + + /* fill in the channels SS7 Stack information */ + sngss7_info->suInstId = get_unique_id(); + sngss7_info->spInstId = spInstId; + + /* try to open the ftdm channel */ + if (ftdm_channel_open_chan(ftdmchan) != FTDM_SUCCESS) { + SS7_ERROR("Failed to open span: %d, chan: %d\n", + ftdmchan->physical_span_id, + ftdmchan->physical_chan_id); + + /* set the flag to indicate this hangup is started from the local side */ + sngss7_set_flag(sngss7_info, FLAG_LOCAL_REL); + + ftdmchan->caller_data.hangup_cause = 41; + + /* move the state to CANCEL */ + ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_CANCEL); + + } else { + + /* fill in cid/ani number */ + if (siConEvnt->cgPtyNum.addrSig.pres) { + copy_tknStr_from_sngss7(siConEvnt->cgPtyNum.addrSig, + ftdmchan->caller_data.cid_num.digits, + siConEvnt->cgPtyNum.oddEven); + + /* fill in cid Name */ + ftdm_set_string(ftdmchan->caller_data.cid_name, ftdmchan->caller_data.cid_num.digits); + + ftdm_set_string(ftdmchan->caller_data.ani.digits, ftdmchan->caller_data.cid_num.digits); + + } else { + SS7_INFO("No Calling party (ANI) information in IAM!\n"); + } + + /* fill in dnis */ + if (siConEvnt->cdPtyNum.addrSig.pres) { + copy_tknStr_from_sngss7(siConEvnt->cdPtyNum.addrSig, + ftdmchan->caller_data.dnis.digits, + siConEvnt->cdPtyNum.oddEven); + } else { + SS7_INFO("No Called party (DNIS) information in IAM!\n"); + } + + /* fill in rdnis */ + if (siConEvnt->redirgNum.addrSig.pres) { + copy_tknStr_from_sngss7(siConEvnt->redirgNum.addrSig, + ftdmchan->caller_data.rdnis.digits, + siConEvnt->cgPtyNum.oddEven); + } else { + SS7_INFO("No RDNIS party information in IAM!\n"); + } + + /* fill in screening/presentation */ + ftdmchan->caller_data.screen = siConEvnt->cgPtyNum.scrnInd.val; + ftdmchan->caller_data.pres = siConEvnt->cgPtyNum.presRest.val; + + /* set the state of the channel to collecting...the rest is done by the chan monitor */ + ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_COLLECT); + + } /* if (ftdm_channel_open_chan(ftdmchan) != FTDM_SUCCESS) */ + + break; + /**************************************************************************/ + default: /* should not have gotten an IAM while in this state */ + SS7_ERROR("Got IAM in an invalid state (%s) on span=%d, chan=%d!\n", + ftdm_channel_state2str(ftdmchan->state), + ftdmchan->physical_span_id, + ftdmchan->physical_chan_id); + + /* move the state of the channel to RESTART to force a reset */ + ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_RESTART); + + break; + /**************************************************************************/ + } /* switch (ftdmchan->state) */ + + /* unlock the channel */ + ftdm_mutex_unlock(ftdmchan->mutex); + + SS7_FUNC_TRACE_EXIT(__FUNCTION__); + return FTDM_SUCCESS; +} + +/******************************************************************************/ +ftdm_status_t handle_con_sta(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, SiCnStEvnt *siCnStEvnt, uint8_t evntType) +{ + SS7_FUNC_TRACE_ENTER(__FUNCTION__); + + sngss7_chan_data_t *sngss7_info ; + ftdm_channel_t *ftdmchan; + + /* get the ftdmchan and ss7_chan_data from the circuit */ + if (extract_chan_data(circuit, &sngss7_info, &ftdmchan)) { + SS7_ERROR("Failed to extract channel data for circuit = %d!\n", circuit); + SS7_FUNC_TRACE_EXIT(__FUNCTION__); + return FTDM_FAIL; + } + + /* now that we have the right channel...put a lock on it so no-one else can use it */ + ftdm_mutex_lock(ftdmchan->mutex); + + /* check if there is a pending state change, give it a bit to clear */ + if (check_for_state_change(ftdmchan)) { + SS7_ERROR("Failed to wait for pending state change on CIC = %d\n", sngss7_info->circuit->cic); + ftdm_mutex_unlock(ftdmchan->mutex); + SS7_FUNC_TRACE_EXIT(__FUNCTION__); + SS7_ASSERT; + } + + switch (evntType) { + /**************************************************************************/ + case (ADDRCMPLT): + SS7_MSG_TRACE(ftdmchan, sngss7_info, "Rx ACM\n"); + switch (ftdmchan->state) { + /**********************************************************************/ + case FTDM_CHANNEL_STATE_DIALING: + /* KONRAD: should we confirm the instance ids ? */ + + /* need to grab the sp instance id */ + sngss7_info->spInstId = spInstId; + + /* go to PROGRESS */ + ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_PROGRESS); + break; + /**********************************************************************/ + default: /* incorrect state...reset the CIC */ + /* go to RESTART */ + ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_PROGRESS); + break; + /**********************************************************************/ + } /* switch (ftdmchan->state) */ + /**************************************************************************/ + case (MODIFY): + SS7_MSG_TRACE(ftdmchan, sngss7_info, "Rx MODIFY\n"); + break; + /**************************************************************************/ + case (MODCMPLT): + SS7_MSG_TRACE(ftdmchan, sngss7_info, "Rx MODIFY-COMPLETE\n"); + break; + /**************************************************************************/ + case (MODREJ): + SS7_MSG_TRACE(ftdmchan, sngss7_info, "Rx MODIFY-REJECT\n"); + break; + /**************************************************************************/ + case (PROGRESS): + SS7_MSG_TRACE(ftdmchan, sngss7_info, "Rx CPG\n"); + break; + /**************************************************************************/ + case (FRWDTRSFR): + SS7_MSG_TRACE(ftdmchan, sngss7_info, "Rx FOT\n"); + break; + /**************************************************************************/ + case (INFORMATION): + SS7_MSG_TRACE(ftdmchan, sngss7_info, "Rx INF\n"); + break; + /**************************************************************************/ + case (INFORMATREQ): + SS7_MSG_TRACE(ftdmchan, sngss7_info, "Rx INR\n"); + break; + /**************************************************************************/ + case (SUBSADDR): + SS7_MSG_TRACE(ftdmchan, sngss7_info, "Rx SAM\n"); + break; + /**************************************************************************/ + case (EXIT): + SS7_MSG_TRACE(ftdmchan, sngss7_info, "Rx EXIT\n"); + break; + /**************************************************************************/ + case (NETRESMGT): + SS7_MSG_TRACE(ftdmchan, sngss7_info, "Rx NRM\n"); + break; + /**************************************************************************/ + case (IDENTREQ): + SS7_MSG_TRACE(ftdmchan, sngss7_info, "Rx IDR\n"); + break; + /**************************************************************************/ + case (IDENTRSP): + SS7_MSG_TRACE(ftdmchan, sngss7_info, "Rx IRS\n"); + break; + /**************************************************************************/ + case (MALCLLPRNT): + SS7_MSG_TRACE(ftdmchan, sngss7_info, "Rx MALICIOUS CALL\n"); + break; + /**************************************************************************/ + case (CHARGE): + SS7_MSG_TRACE(ftdmchan, sngss7_info, "Rx CRG\n"); + break; + /**************************************************************************/ + case (TRFFCHGE): + SS7_MSG_TRACE(ftdmchan, sngss7_info, "Rx CRG-TARIFF\n"); + break; + /**************************************************************************/ + case (CHARGEACK): + SS7_MSG_TRACE(ftdmchan, sngss7_info, "Rx CRG-ACK\n"); + break; + /**************************************************************************/ + case (CALLOFFMSG): + SS7_MSG_TRACE(ftdmchan, sngss7_info, "Rx CALL-OFFER\n"); + break; + /**************************************************************************/ + case (LOOPPRVNT): + SS7_MSG_TRACE(ftdmchan, sngss7_info, "Rx LOP\n"); + break; + /**************************************************************************/ + case (TECT_TIMEOUT): + SS7_MSG_TRACE(ftdmchan, sngss7_info, "Rx ECT-Timeout\n"); + break; + /**************************************************************************/ + case (RINGSEND): + SS7_MSG_TRACE(ftdmchan, sngss7_info, "Rx RINGING-SEND\n"); + break; + /**************************************************************************/ + case (CALLCLEAR): + SS7_MSG_TRACE(ftdmchan, sngss7_info, "Rx CALL-LINE Clear\n"); + break; + /**************************************************************************/ + case (PRERELEASE): + SS7_MSG_TRACE(ftdmchan, sngss7_info, "Rx PRI\n"); + break; + /**************************************************************************/ + case (APPTRANSPORT): + SS7_MSG_TRACE(ftdmchan, sngss7_info, "Rx APM\n"); + break; + /**************************************************************************/ + case (OPERATOR): + SS7_MSG_TRACE(ftdmchan, sngss7_info, "Rx OPERATOR\n"); + break; + /**************************************************************************/ + case (METPULSE): + SS7_MSG_TRACE(ftdmchan, sngss7_info, "Rx METERING-PULSE\n"); + break; + /**************************************************************************/ + case (CLGPTCLR): + SS7_MSG_TRACE(ftdmchan, sngss7_info, "Rx CALLING_PARTY_CLEAR\n"); + break; + /**************************************************************************/ + case (SUBDIRNUM): + SS7_MSG_TRACE(ftdmchan, sngss7_info, "Rx SUB-DIR\n"); + break; + /**************************************************************************/ + default: + SS7_MSG_TRACE(ftdmchan, sngss7_info, "Rx Unknown Msg\n"); + break; + /**************************************************************************/ + } + + /* unlock the channel */ + ftdm_mutex_unlock(ftdmchan->mutex); + + SS7_FUNC_TRACE_EXIT(__FUNCTION__); + return FTDM_SUCCESS; +} + +/******************************************************************************/ +ftdm_status_t handle_con_cfm(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, SiConEvnt *siConEvnt) +{ + SS7_FUNC_TRACE_ENTER(__FUNCTION__); + + sngss7_chan_data_t *sngss7_info ; + ftdm_channel_t *ftdmchan; + + /* get the ftdmchan and ss7_chan_data from the circuit */ + if (extract_chan_data(circuit, &sngss7_info, &ftdmchan)) { + SS7_ERROR("Failed to extract channel data for circuit = %d!\n", circuit); + SS7_FUNC_TRACE_EXIT(__FUNCTION__); + return FTDM_FAIL; + } + + /* now that we have the right channel...put a lock on it so no-one else can use it */ + ftdm_mutex_lock(ftdmchan->mutex); + + /* check if there is a pending state change, give it a bit to clear */ + if (check_for_state_change(ftdmchan)) { + SS7_ERROR("Failed to wait for pending state change on CIC = %d\n", sngss7_info->circuit->cic); + ftdm_mutex_unlock(ftdmchan->mutex); + SS7_FUNC_TRACE_EXIT(__FUNCTION__); + SS7_ASSERT; + }; + + + /* check whether the ftdm channel is in a state to accept a call */ + switch (ftdmchan->state) { + /**************************************************************************/ + case FTDM_CHANNEL_STATE_PROGRESS: + case FTDM_CHANNEL_STATE_PROGRESS_MEDIA: + + SS7_MSG_TRACE(ftdmchan, sngss7_info, "Rx ANM\n"); + + /* go to UP */ + ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_UP); + + break; + /**************************************************************************/ + case FTDM_CHANNEL_STATE_DIALING: + + SS7_MSG_TRACE(ftdmchan, sngss7_info, "Rx CON\n"); + + /* go to UP */ + ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_UP); + + break; + /**************************************************************************/ + default: /* incorrect state...reset the CIC */ + + SS7_MSG_TRACE(ftdmchan, sngss7_info, "Rx ANM/CON\n"); + + /* throw the TX reset flag */ + sngss7_set_flag(sngss7_info, FLAG_GRP_RESET_TX); + + /* go to RESTART */ + ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_RESTART); + + break; + /**************************************************************************/ + } + + /* unlock the channel */ + ftdm_mutex_unlock(ftdmchan->mutex); + + SS7_FUNC_TRACE_EXIT(__FUNCTION__); + return FTDM_SUCCESS; +} + +/******************************************************************************/ +ftdm_status_t handle_rel_ind(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, SiRelEvnt *siRelEvnt) +{ + SS7_FUNC_TRACE_ENTER(__FUNCTION__); + + sngss7_chan_data_t *sngss7_info ; + ftdm_channel_t *ftdmchan; + + /* get the ftdmchan and ss7_chan_data from the circuit */ + if (extract_chan_data(circuit, &sngss7_info, &ftdmchan)) { + SS7_ERROR("Failed to extract channel data for circuit = %d!\n", circuit); + SS7_FUNC_TRACE_EXIT(__FUNCTION__); + return FTDM_FAIL; + } + + /* now that we have the right channel...put a lock on it so no-one else can use it */ + ftdm_mutex_lock(ftdmchan->mutex); + + /* check if there is a pending state change, give it a bit to clear */ + if (check_for_state_change(ftdmchan)) { + SS7_ERROR("Failed to wait for pending state change on CIC = %d\n", sngss7_info->circuit->cic); + ftdm_mutex_unlock(ftdmchan->mutex); + SS7_FUNC_TRACE_EXIT(__FUNCTION__); + SS7_ASSERT; + }; + + SS7_MSG_TRACE(ftdmchan, sngss7_info, "Rx REL\n"); + + /* check whether the ftdm channel is in a state to release a call */ + switch (ftdmchan->state) { + /**************************************************************************/ + case FTDM_CHANNEL_STATE_DIALING: + + /* pass the release code up to FTDM */ + if (siRelEvnt->causeDgn.causeVal.pres) { + ftdmchan->caller_data.hangup_cause = siRelEvnt->causeDgn.causeVal.val; + } else { + SS7_ERROR("REL does not have a cause code!\n"); + ftdmchan->caller_data.hangup_cause = 0; + } + + /* this is a remote hangup request */ + sngss7_set_flag(sngss7_info, FLAG_REMOTE_REL); + + /* move the state of the channel to CANCEL to end the call */ + ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_TERMINATING); + + break; + /**************************************************************************/ + case FTDM_CHANNEL_STATE_RING: + case FTDM_CHANNEL_STATE_PROGRESS: + case FTDM_CHANNEL_STATE_PROGRESS_MEDIA: + case FTDM_CHANNEL_STATE_UP: + + /* pass the release code up to FTDM */ + if (siRelEvnt->causeDgn.causeVal.pres) { + ftdmchan->caller_data.hangup_cause = siRelEvnt->causeDgn.causeVal.val; + } else { + SS7_ERROR("REL does not have a cause code!\n"); + ftdmchan->caller_data.hangup_cause = 0; + } + + /* this is a remote hangup request */ + sngss7_set_flag(sngss7_info, FLAG_REMOTE_REL); + + /* move the state of the channel to TERMINATING to end the call */ + ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_TERMINATING); + + break; + /**************************************************************************/ + default: + + /* fill in the channels SS7 Stack information */ + sngss7_info->suInstId = get_unique_id(); + sngss7_info->spInstId = spInstId; + + /* throw the reset flag */ + sngss7_set_flag(sngss7_info, FLAG_RESET_RX); + + /* set the state to RESTART */ + ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_RESTART); + break; + /**************************************************************************/ + } /* switch (ftdmchan->state) */ + + + /* unlock the channel */ + ftdm_mutex_unlock(ftdmchan->mutex); + + SS7_FUNC_TRACE_EXIT(__FUNCTION__); + return FTDM_SUCCESS; +} + +/******************************************************************************/ +ftdm_status_t handle_rel_cfm(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, SiRelEvnt *siRelEvnt) +{ + SS7_FUNC_TRACE_ENTER(__FUNCTION__); + + sngss7_chan_data_t *sngss7_info ; + ftdm_channel_t *ftdmchan; + + /* get the ftdmchan and ss7_chan_data from the circuit */ + if (extract_chan_data(circuit, &sngss7_info, &ftdmchan)) { + SS7_ERROR("Failed to extract channel data for circuit = %d!\n", circuit); + SS7_FUNC_TRACE_EXIT(__FUNCTION__); + return FTDM_FAIL; + } + + /* now that we have the right channel...put a lock on it so no-one else can use it */ + ftdm_mutex_lock(ftdmchan->mutex); + + /* check if there is a pending state change, give it a bit to clear */ + if (check_for_state_change(ftdmchan)) { + SS7_ERROR("Failed to wait for pending state change on CIC = %d\n", sngss7_info->circuit->cic); + ftdm_mutex_unlock(ftdmchan->mutex); + SS7_FUNC_TRACE_EXIT(__FUNCTION__); + SS7_ASSERT; + }; + + SS7_MSG_TRACE(ftdmchan, sngss7_info, "Rx RLC\n"); + + /* check whether the ftdm channel is in a state to accept a call */ + switch (ftdmchan->state) { + /**************************************************************************/ + case FTDM_CHANNEL_STATE_HANGUP_COMPLETE: + + /* go to DOWN */ + ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_DOWN); + + break; + /**************************************************************************/ + case FTDM_CHANNEL_STATE_DOWN: + /* do nothing, just drop the message */ + break; + /**************************************************************************/ + default: + /* KONRAD: should just stop the call...but a reset is easier for now (since it does hangup the call) */ + + /* go to RESTART */ + ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_RESTART); + + break; + /**************************************************************************/ + } + + /* unlock the channel */ + ftdm_mutex_unlock(ftdmchan->mutex); + + SS7_FUNC_TRACE_EXIT(__FUNCTION__); + return FTDM_SUCCESS; +} + +/******************************************************************************/ +ftdm_status_t handle_dat_ind(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, SiInfoEvnt *siInfoEvnt) +{ + SS7_FUNC_TRACE_ENTER(__FUNCTION__); + + sngss7_chan_data_t *sngss7_info ; + ftdm_channel_t *ftdmchan; + + /* get the ftdmchan and ss7_chan_data from the circuit */ + if (extract_chan_data(circuit, &sngss7_info, &ftdmchan)) { + SS7_ERROR("Failed to extract channel data for circuit = %d!\n", circuit); + SS7_FUNC_TRACE_EXIT(__FUNCTION__); + return FTDM_FAIL; + } + + /* now that we have the right channel...put a lock on it so no-one else can use it */ + ftdm_mutex_lock(ftdmchan->mutex); + + /* check if there is a pending state change, give it a bit to clear */ + if (check_for_state_change(ftdmchan)) { + SS7_ERROR("Failed to wait for pending state change on CIC = %d\n", sngss7_info->circuit->cic); + ftdm_mutex_unlock(ftdmchan->mutex); + SS7_FUNC_TRACE_EXIT(__FUNCTION__); + SS7_ASSERT; + }; + + SS7_MSG_TRACE(ftdmchan, sngss7_info, "Rx DATA IND\n"); + + /* unlock the channel */ + ftdm_mutex_unlock(ftdmchan->mutex); + + SS7_FUNC_TRACE_EXIT(__FUNCTION__); + return FTDM_SUCCESS; +} + +/******************************************************************************/ +ftdm_status_t handle_fac_ind(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, uint8_t evntType, SiFacEvnt *siFacEvnt) +{ + SS7_FUNC_TRACE_ENTER(__FUNCTION__); + + sngss7_chan_data_t *sngss7_info ; + ftdm_channel_t *ftdmchan; + + /* get the ftdmchan and ss7_chan_data from the circuit */ + if (extract_chan_data(circuit, &sngss7_info, &ftdmchan)) { + SS7_ERROR("Failed to extract channel data for circuit = %d!\n", circuit); + SS7_FUNC_TRACE_EXIT(__FUNCTION__); + return FTDM_FAIL; + } + + /* now that we have the right channel...put a lock on it so no-one else can use it */ + ftdm_mutex_lock(ftdmchan->mutex); + + /* check if there is a pending state change, give it a bit to clear */ + if (check_for_state_change(ftdmchan)) { + SS7_ERROR("Failed to wait for pending state change on CIC = %d\n", sngss7_info->circuit->cic); + ftdm_mutex_unlock(ftdmchan->mutex); + SS7_FUNC_TRACE_EXIT(__FUNCTION__); + SS7_ASSERT; + }; + + SS7_MSG_TRACE(ftdmchan, sngss7_info, "Rx FAC\n"); + + /* unlock the channel */ + ftdm_mutex_unlock(ftdmchan->mutex); + + SS7_FUNC_TRACE_EXIT(__FUNCTION__); + return FTDM_SUCCESS; +} + +/******************************************************************************/ +ftdm_status_t handle_fac_cfm(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, uint8_t evntType, SiFacEvnt *siFacEvnt) +{ + SS7_FUNC_TRACE_ENTER(__FUNCTION__); + + sngss7_chan_data_t *sngss7_info ; + ftdm_channel_t *ftdmchan; + + /* get the ftdmchan and ss7_chan_data from the circuit */ + if (extract_chan_data(circuit, &sngss7_info, &ftdmchan)) { + SS7_ERROR("Failed to extract channel data for circuit = %d!\n", circuit); + SS7_FUNC_TRACE_EXIT(__FUNCTION__); + return FTDM_FAIL; + } + + /* now that we have the right channel...put a lock on it so no-one else can use it */ + ftdm_mutex_lock(ftdmchan->mutex); + + /* check if there is a pending state change, give it a bit to clear */ + if (check_for_state_change(ftdmchan)) { + SS7_ERROR("Failed to wait for pending state change on CIC = %d\n", sngss7_info->circuit->cic); + ftdm_mutex_unlock(ftdmchan->mutex); + SS7_FUNC_TRACE_EXIT(__FUNCTION__); + SS7_ASSERT; + }; + + SS7_MSG_TRACE(ftdmchan, sngss7_info, "Rx FAC-CON\n"); + + /* unlock the channel */ + ftdm_mutex_unlock(ftdmchan->mutex); + + SS7_FUNC_TRACE_EXIT(__FUNCTION__); + return FTDM_SUCCESS; +} + +/******************************************************************************/ +ftdm_status_t handle_umsg_ind(uint32_t suInstId, uint32_t spInstId, uint32_t circuit) +{ + SS7_FUNC_TRACE_ENTER(__FUNCTION__); + + sngss7_chan_data_t *sngss7_info ; + ftdm_channel_t *ftdmchan; + + /* get the ftdmchan and ss7_chan_data from the circuit */ + if (extract_chan_data(circuit, &sngss7_info, &ftdmchan)) { + SS7_ERROR("Failed to extract channel data for circuit = %d!\n", circuit); + SS7_FUNC_TRACE_EXIT(__FUNCTION__); + return FTDM_FAIL; + } + + /* now that we have the right channel...put a lock on it so no-one else can use it */ + ftdm_mutex_lock(ftdmchan->mutex); + + /* check if there is a pending state change, give it a bit to clear */ + if (check_for_state_change(ftdmchan)) { + SS7_ERROR("Failed to wait for pending state change on CIC = %d\n", sngss7_info->circuit->cic); + ftdm_mutex_unlock(ftdmchan->mutex); + SS7_FUNC_TRACE_EXIT(__FUNCTION__); + SS7_ASSERT; + }; + + SS7_MSG_TRACE(ftdmchan, sngss7_info, "Rx USER-USER msg\n"); + + /* unlock the channel */ + ftdm_mutex_unlock(ftdmchan->mutex); + + SS7_FUNC_TRACE_EXIT(__FUNCTION__); + return FTDM_SUCCESS; +} + +/******************************************************************************/ +ftdm_status_t handle_sta_ind(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, uint8_t globalFlg, uint8_t evntType, SiStaEvnt *siStaEvnt) +{ + sngss7_chan_data_t *sngss7_info ; + ftdm_channel_t *ftdmchan; + + /* get the ftdmchan and ss7_chan_data from the circuit */ + if (extract_chan_data(circuit, &sngss7_info, &ftdmchan)) { + SS7_ERROR("Failed to extract channel data for circuit = %d!\n", circuit); + SS7_FUNC_TRACE_EXIT(__FUNCTION__); + return FTDM_FAIL; + } + + SS7_FUNC_TRACE_ENTER(__FUNCTION__); + + switch (evntType) { + /**************************************************************************/ + case SIT_STA_REATTEMPT: /* reattempt indication */ + SS7_MSG_TRACE(ftdmchan, sngss7_info, "Rx Reattempt indication\n"); + handle_reattempt(suInstId, spInstId, circuit, globalFlg, evntType, siStaEvnt); + break; + /**************************************************************************/ + case SIT_STA_ERRORIND: /* error indication */ + SS7_MSG_TRACE(ftdmchan, sngss7_info, "Rx Error indication\n"); + SS7_WARN(" %s indication not currently supported\n", DECODE_LCC_EVENT(evntType)); + break; + /**************************************************************************/ + case SIT_STA_CONTCHK: /* continuity check */ + SS7_MSG_TRACE(ftdmchan, sngss7_info, "Rx COT start\n"); + handle_cot_start(suInstId, spInstId, circuit, globalFlg, evntType, siStaEvnt); + break; + /**************************************************************************/ + case SIT_STA_CONTREP: /* continuity report */ + SS7_MSG_TRACE(ftdmchan, sngss7_info, "Rx COT report\n"); + handle_cot(suInstId, spInstId, circuit, globalFlg, evntType, siStaEvnt); + break; + /**************************************************************************/ + case SIT_STA_STPCONTIN: /* stop continuity */ + SS7_MSG_TRACE(ftdmchan, sngss7_info, "Rx COT stop\n"); + handle_cot_stop(suInstId, spInstId, circuit, globalFlg, evntType, siStaEvnt); + break; + /**************************************************************************/ + case SIT_STA_CGQRYRSP: /* circuit grp query response from far end forwarded to upper layer by ISUP */ + SS7_MSG_TRACE(ftdmchan, sngss7_info, "Rx CQM\n"); + SS7_WARN(" %s indication not currently supported\n", DECODE_LCC_EVENT(evntType)); + break; + /**************************************************************************/ + case SIT_STA_CONFUSION: /* confusion */ + SS7_MSG_TRACE(ftdmchan, sngss7_info, "Rx CFN\n"); + SS7_WARN(" %s indication not currently supported\n", DECODE_LCC_EVENT(evntType)); + break; + /**************************************************************************/ + case SIT_STA_LOOPBACKACK: /* loop-back acknowledge */ + SS7_MSG_TRACE(ftdmchan, sngss7_info, "Rx LPA\n"); + SS7_WARN(" %s indication not currently supported\n", DECODE_LCC_EVENT(evntType)); + break; + /**************************************************************************/ + case SIT_STA_CIRRSRVREQ: /* circuit reservation request */ + SS7_MSG_TRACE(ftdmchan, sngss7_info, "Rx Ckt Resveration req\n"); + SS7_WARN(" %s indication not currently supported\n", DECODE_LCC_EVENT(evntType)); + break; + /**************************************************************************/ + case SIT_STA_CIRRSRVACK: /* circuit reservation acknowledgement */ + SS7_MSG_TRACE(ftdmchan, sngss7_info, "Rx Ckt Res ack\n"); + SS7_WARN(" %s indication not currently supported\n", DECODE_LCC_EVENT(evntType)); + break; + /**************************************************************************/ + case SIT_STA_CIRBLOREQ: /* circuit blocking request */ + SS7_MSG_TRACE(ftdmchan, sngss7_info, "Rx BLO\n"); + handle_blo_req(suInstId, spInstId, circuit, globalFlg, evntType, siStaEvnt); + break; + /**************************************************************************/ + case SIT_STA_CIRBLORSP: /* circuit blocking response */ + SS7_MSG_TRACE(ftdmchan, sngss7_info, "Rx BLA\n"); + handle_blo_rsp(suInstId, spInstId, circuit, globalFlg, evntType, siStaEvnt); + break; + /**************************************************************************/ + case SIT_STA_CIRUBLREQ: /* circuit unblocking request */ + SS7_MSG_TRACE(ftdmchan, sngss7_info, "Rx UBL\n"); + handle_ubl_req(suInstId, spInstId, circuit, globalFlg, evntType, siStaEvnt); + break; + /**************************************************************************/ + case SIT_STA_CIRUBLRSP: /* circuit unblocking response */ + SS7_MSG_TRACE(ftdmchan, sngss7_info, "Rx UBA\n"); + handle_ubl_rsp(suInstId, spInstId, circuit, globalFlg, evntType, siStaEvnt); + break; + /**************************************************************************/ + case SIT_STA_CIRRESREQ: /* circuit reset request - RSC */ + SS7_MSG_TRACE(ftdmchan, sngss7_info, "Rx RSC\n"); + handle_rsc_req(suInstId, spInstId, circuit, globalFlg, evntType, siStaEvnt); + break; + /**************************************************************************/ + case SIT_STA_CIRLOCRES: /* reset initiated locally by the software */ + SS7_MSG_TRACE(ftdmchan, sngss7_info, "Rx Local RSC\n"); + handle_local_rsc_req(suInstId, spInstId, circuit, globalFlg, evntType, siStaEvnt); + break; + /**************************************************************************/ + case SIT_STA_CIRRESRSP: /* circuit reset response */ + SS7_MSG_TRACE(ftdmchan, sngss7_info, "Rx RSC-RLC\n"); + handle_rsc_rsp(suInstId, spInstId, circuit, globalFlg, evntType, siStaEvnt); + break; + /**************************************************************************/ + case SIT_STA_CGBREQ: /* CGB request */ + SS7_MSG_TRACE(ftdmchan, sngss7_info, "Rx CGB\n"); + SS7_WARN(" %s indication not currently supported\n", DECODE_LCC_EVENT(evntType)); + break; + /**************************************************************************/ + case SIT_STA_CGUREQ: /* CGU request */ + SS7_MSG_TRACE(ftdmchan, sngss7_info, "Rx CGU\n"); + SS7_WARN(" %s indication not currently supported\n", DECODE_LCC_EVENT(evntType)); + break; + /**************************************************************************/ + case SIT_STA_CGQRYREQ: /* circuit group query request */ + SS7_MSG_TRACE(ftdmchan, sngss7_info, "Rx CQM\n"); + SS7_WARN(" %s indication not currently supported\n", DECODE_LCC_EVENT(evntType)); + break; + /**************************************************************************/ + case SIT_STA_CGBRSP: /* mntc. oriented CGB response */ + SS7_MSG_TRACE(ftdmchan, sngss7_info, "Rx mntc CGB\n"); + SS7_WARN(" %s indication not currently supported\n", DECODE_LCC_EVENT(evntType)); + break; + /**************************************************************************/ + case SIT_STA_CGURSP: /* mntc. oriented CGU response */ + SS7_MSG_TRACE(ftdmchan, sngss7_info, "Rx mntc CGU\n"); + SS7_WARN(" %s indication not currently supported\n", DECODE_LCC_EVENT(evntType)); + break; + /**************************************************************************/ + case SIT_STA_GRSREQ: /* circuit group reset request */ + SS7_MSG_TRACE(ftdmchan, sngss7_info, "Rx GRS\n"); + handle_grs_req(suInstId, spInstId, circuit, globalFlg, evntType, siStaEvnt); + break; + /**************************************************************************/ + case SIT_STA_CIRUNEQPD: /* circuit unequipped indication */ + SS7_MSG_TRACE(ftdmchan, sngss7_info, "Rx UCIC\n"); + handle_ucic(suInstId, spInstId, circuit, globalFlg, evntType, siStaEvnt); + break; + /**************************************************************************/ + case SIT_STA_GRSRSP: /* circuit group reset response */ + SS7_MSG_TRACE(ftdmchan, sngss7_info, "Rx GRA\n"); + handle_grs_rsp(suInstId, spInstId, circuit, globalFlg, evntType, siStaEvnt); + break; + /**************************************************************************/ + case SIT_STA_PAUSEIND: /* pause indication */ + SS7_MSG_TRACE(ftdmchan, sngss7_info, "Rx SUS\n"); + handle_pause(suInstId, spInstId, circuit, globalFlg, evntType, siStaEvnt); + break; + /**************************************************************************/ + case SIT_STA_RESUMEIND: /* resume indication */ + SS7_MSG_TRACE(ftdmchan, sngss7_info, "Rx RES\n"); + handle_resume(suInstId, spInstId, circuit, globalFlg, evntType, siStaEvnt); + break; + /**************************************************************************/ + case SIT_STA_USRPARTA: /* user part available */ + SS7_MSG_TRACE(ftdmchan, sngss7_info, "Rx UPA\n"); + SS7_WARN(" %s indication not currently supported\n", DECODE_LCC_EVENT(evntType)); + break; + /**************************************************************************/ + case SIT_STA_RMTUSRUNAV: /* remote user not available */ + SS7_MSG_TRACE(ftdmchan, sngss7_info, "Rx Remote User not Available\n"); + SS7_WARN(" %s indication not currently supported\n", DECODE_LCC_EVENT(evntType)); + break; + /**************************************************************************/ + case SIT_STA_MTPCONG0: /* congestion indication level 0 */ + SS7_MSG_TRACE(ftdmchan, sngss7_info, "Rx Congestion L0\n"); + SS7_WARN(" %s indication not currently supported\n", DECODE_LCC_EVENT(evntType)); + break; + /**************************************************************************/ + case SIT_STA_MTPCONG1: /* congestion indication level 1 */ + SS7_MSG_TRACE(ftdmchan, sngss7_info, "Rx Congestion L1\n"); + SS7_WARN(" %s indication not currently supported\n", DECODE_LCC_EVENT(evntType)); + break; + /**************************************************************************/ + case SIT_STA_MTPCONG2: /* congestion indication level 2 */ + SS7_MSG_TRACE(ftdmchan, sngss7_info, "Rx Congestion L2\n"); + SS7_WARN(" %s indication not currently supported\n", DECODE_LCC_EVENT(evntType)); + break; + /**************************************************************************/ + case SIT_STA_MTPCONG3: /* congestion indication level 3 */ + SS7_MSG_TRACE(ftdmchan, sngss7_info, "Rx Congestion L3\n"); + SS7_WARN(" %s indication not currently supported\n", DECODE_LCC_EVENT(evntType)); + break; + /**************************************************************************/ + case SIT_STA_MTPSTPCONG: /* stop congestion indication level 0 */ + SS7_MSG_TRACE(ftdmchan, sngss7_info, "Rx Stop Congestion\n"); + SS7_WARN(" %s indication not currently supported\n", DECODE_LCC_EVENT(evntType)); + break; + /**************************************************************************/ + case SIT_STA_CIRLOCALBLOIND: /* Mngmt local blocking */ + SS7_MSG_TRACE(ftdmchan, sngss7_info, "Rx Local BLO\n"); + handle_local_blk(suInstId, spInstId, circuit, globalFlg, evntType, siStaEvnt); + break; + /**************************************************************************/ + case SIT_STA_CIRLOCALUBLIND: /* Mngmt local unblocking */ + SS7_MSG_TRACE(ftdmchan, sngss7_info, "Rx Local UBL\n"); + handle_local_ubl(suInstId, spInstId, circuit, globalFlg, evntType, siStaEvnt); + break; + /**************************************************************************/ + case SIT_STA_OVERLOAD: /* Overload */ + SS7_MSG_TRACE(ftdmchan, sngss7_info, "Rx Overload\n"); + SS7_WARN(" %s indication not currently supported\n", DECODE_LCC_EVENT(evntType)); + break; + /**************************************************************************/ + case SIT_STA_LMCGBREQ: /* when LM requests ckt grp blocking */ + SS7_MSG_TRACE(ftdmchan, sngss7_info, "Rx LM CGB\n"); + SS7_WARN(" %s indication not currently supported\n", DECODE_LCC_EVENT(evntType)); + break; + /**************************************************************************/ + case SIT_STA_LMCGUREQ: /* when LM requests ckt grp unblocking */ + SS7_MSG_TRACE(ftdmchan, sngss7_info, "Rx LM CGU\n"); + SS7_WARN(" %s indication not currently supported\n", DECODE_LCC_EVENT(evntType)); + break; + /**************************************************************************/ + case SIT_STA_LMGRSREQ: /* when LM requests ckt grp reset */ + SS7_MSG_TRACE(ftdmchan, sngss7_info, "Rx LM RSC\n"); + SS7_WARN(" %s indication not currently supported\n", DECODE_LCC_EVENT(evntType)); + break; + /**************************************************************************/ + case SIT_STA_CGBINFOIND: /* circuit grp blking ind , no resp req */ + SS7_MSG_TRACE(ftdmchan, sngss7_info, "Rx CGB no resp req\n"); + SS7_WARN(" %s indication not currently supported\n", DECODE_LCC_EVENT(evntType)); + break; + /**************************************************************************/ + case SIT_STA_LMCQMINFOREQ: /* when LM requests ckt grp query */ + SS7_MSG_TRACE(ftdmchan, sngss7_info, "Rx LM CQM\n"); + SS7_WARN(" %s indication not currently supported\n", DECODE_LCC_EVENT(evntType)); + break; + /**************************************************************************/ + case SIT_STA_CIRLOCGRS: /* group reset initiated locally by the software */ + SS7_MSG_TRACE(ftdmchan, sngss7_info, "Rx Local GRS\n"); + SS7_WARN(" %s indication not currently supported\n", DECODE_LCC_EVENT(evntType)); + break; + /**************************************************************************/ + default: + SS7_INFO("[SNG-CC] Received Unknown indication %d\n", evntType); + break; + } /* switch (evntType) */ + + SS7_FUNC_TRACE_EXIT(__FUNCTION__); + return FTDM_SUCCESS; + +} + +/******************************************************************************/ +ftdm_status_t handle_reattempt(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, uint8_t globalFlg, uint8_t evntType, SiStaEvnt *siStaEvnt) +{ + SS7_FUNC_TRACE_ENTER(__FUNCTION__); + + sngss7_chan_data_t *sngss7_info = NULL; + ftdm_channel_t *ftdmchan = NULL; + + /* get the ftdmchan and ss7_chan_data from the circuit */ + if (extract_chan_data(circuit, &sngss7_info, &ftdmchan)) { + SS7_ERROR("Failed to extract channel data for ISUP circuit = %d!\n", circuit); + SS7_FUNC_TRACE_EXIT(__FUNCTION__); + return FTDM_FAIL; + } + + /* now that we have the right channel...put a lock on it so no-one else can use it */ + ftdm_mutex_lock(ftdmchan->mutex); + + /* check if there is a pending state change, give it a bit to clear */ + if (check_for_state_change(ftdmchan)) { + SS7_ERROR("Failed to wait for pending state change on CIC = %d\n", sngss7_info->circuit->cic); + ftdm_mutex_unlock(ftdmchan->mutex); + SS7_FUNC_TRACE_EXIT(__FUNCTION__); + SS7_ASSERT; + }; + + /* glare, throw the flag, go to down state*/ + sngss7_set_flag(sngss7_info, FLAG_GLARE); + + ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_CANCEL); + + /* unlock the channel again before we exit */ + ftdm_mutex_unlock(ftdmchan->mutex); + + SS7_FUNC_TRACE_EXIT(__FUNCTION__); + return FTDM_SUCCESS; +} + +/******************************************************************************/ +ftdm_status_t handle_pause(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, uint8_t globalFlg, uint8_t evntType, SiStaEvnt *siStaEvnt) +{ + SS7_FUNC_TRACE_ENTER(__FUNCTION__); + + sngss7_chan_data_t *sngss7_info = NULL; + ftdm_channel_t *ftdmchan = NULL; + int infId; + int i; + + /* extract the affect infId from the circuit structure */ + infId = g_ftdm_sngss7_data.cfg.isupCkt[circuit].infId; + + /* go through all the circuits now and find any other circuits on this infId */ + i = 1; + while (g_ftdm_sngss7_data.cfg.isupCkt[i].id != 0) { + + /* check that the infId matches and that this is not a siglink */ + if ((g_ftdm_sngss7_data.cfg.isupCkt[i].infId == infId) && + (g_ftdm_sngss7_data.cfg.isupCkt[i].type == VOICE)) { + + /* get the ftdmchan and ss7_chan_data from the circuit */ + if (extract_chan_data(i, &sngss7_info, &ftdmchan)) { + SS7_ERROR("Failed to extract channel data for circuit = %d!\n", circuit); + i++; + continue; + } + + /* lock the channel */ + ftdm_mutex_lock(ftdmchan->mutex); + + /* check if there is a pending state change, give it a bit to clear */ + if (check_for_state_change(ftdmchan)) { + SS7_ERROR("Failed to wait for pending state change on CIC = %d\n", sngss7_info->circuit->cic); + ftdm_mutex_unlock(ftdmchan->mutex); + i++; + SS7_ASSERT; + }; + + /* check if the circuit is fully started */ + if (ftdm_test_flag(ftdmchan->span, FTDM_SPAN_IN_THREAD)) { + /* set the pause flag on the channel */ + sngss7_set_flag(sngss7_info, FLAG_INFID_PAUSED); + + /* set the statet o SUSPENDED to bring the sig status down */ + ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_SUSPENDED); + } + + /* unlock the channel again before we exit */ + ftdm_mutex_unlock(ftdmchan->mutex); + + } /* if (g_ftdm_sngss7_data.cfg.isupCkt[i].infId == infId) */ + + /* move to the next circuit */ + i++; + + } /* while (g_ftdm_sngss7_data.cfg.isupCkt[i].id != 0) */ + + SS7_FUNC_TRACE_EXIT(__FUNCTION__); + return FTDM_SUCCESS; +} + +/******************************************************************************/ +ftdm_status_t handle_resume(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, uint8_t globalFlg, uint8_t evntType, SiStaEvnt *siStaEvnt) +{ + SS7_FUNC_TRACE_ENTER(__FUNCTION__); + + sngss7_chan_data_t *sngss7_info = NULL; + ftdm_channel_t *ftdmchan = NULL; + int infId; + int i; + + /* extract the affect infId from the circuit structure */ + infId = g_ftdm_sngss7_data.cfg.isupCkt[circuit].infId; + + /* go through all the circuits now and find any other circuits on this infId */ + i = 1; + while (g_ftdm_sngss7_data.cfg.isupCkt[i].id != 0) { + + /* check that the infId matches and that this is not a siglink */ + if ((g_ftdm_sngss7_data.cfg.isupCkt[i].infId == infId) && + (g_ftdm_sngss7_data.cfg.isupCkt[i].type == VOICE)) { + + /* get the ftdmchan and ss7_chan_data from the circuit */ + if (extract_chan_data(i, &sngss7_info, &ftdmchan)) { + SS7_ERROR("Failed to extract channel data for circuit = %d!\n", circuit); + i++; + continue; + } + + /* lock the channel */ + ftdm_mutex_lock(ftdmchan->mutex); + + /* check if there is a pending state change, give it a bit to clear */ + if (check_for_state_change(ftdmchan)) { + SS7_ERROR("Failed to wait for pending state change on CIC = %d\n", sngss7_info->circuit->cic); + ftdm_mutex_unlock(ftdmchan->mutex); + i++; + SS7_ASSERT; + }; + + /* only resume if we are paused */ + if (sngss7_test_flag(sngss7_info, FLAG_INFID_PAUSED)) { + /* set the resume flag on the channel */ + sngss7_set_flag(sngss7_info, FLAG_INFID_RESUME); + + /* clear the paused flag */ + sngss7_clear_flag(sngss7_info, FLAG_INFID_PAUSED); + + /* set the statet to SUSPENDED to bring the sig status up */ + ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_SUSPENDED); + } + + /* unlock the channel again before we exit */ + ftdm_mutex_unlock(ftdmchan->mutex); + + } /* if (g_ftdm_sngss7_data.cfg.isupCkt[i].infId == infId) */ + + /* move to the next circuit */ + i++; + + } /* while (g_ftdm_sngss7_data.cfg.isupCkt[i].id != 0) */ + + SS7_FUNC_TRACE_EXIT(__FUNCTION__); + return FTDM_SUCCESS; +} + +/******************************************************************************/ +ftdm_status_t handle_cot_start(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, uint8_t globalFlg, uint8_t evntType, SiStaEvnt *siStaEvnt) +{ + SS7_FUNC_TRACE_ENTER(__FUNCTION__); + + sngss7_chan_data_t *sngss7_info = NULL; + ftdm_channel_t *ftdmchan = NULL; + + /* get the ftdmchan and ss7_chan_data from the circuit */ + if (extract_chan_data(circuit, &sngss7_info, &ftdmchan)) { + SS7_ERROR("Failed to extract channel data for circuit = %d!\n", circuit); + SS7_FUNC_TRACE_EXIT(__FUNCTION__); + return FTDM_FAIL; + } + + /* now that we have the right channel...put a lock on it so no-one else can use it */ + ftdm_mutex_lock(ftdmchan->mutex); + + /* check if there is a pending state change, give it a bit to clear */ + if (check_for_state_change(ftdmchan)) { + SS7_ERROR("Failed to wait for pending state change on CIC = %d\n", sngss7_info->circuit->cic); + ftdm_mutex_unlock(ftdmchan->mutex); + SS7_FUNC_TRACE_EXIT(__FUNCTION__); + SS7_ASSERT; + }; + + /* open the channel if it is not open */ + if (!ftdm_test_flag(ftdmchan, FTDM_CHANNEL_OPEN)) { + if (ftdm_channel_open_chan(ftdmchan) != FTDM_SUCCESS) { + SS7_ERROR("Failed to open CIC %d for COT test!\n", sngss7_info->circuit->cic); + /* KONRAD FIX ME */ + SS7_FUNC_TRACE_EXIT(__FUNCTION__); + return FTDM_FAIL; + } + } + + /* tell the core to loop the channel */ + ftdm_channel_command(ftdmchan, FTDM_COMMAND_ENABLE_LOOP, NULL); + + /* switch to the IN_LOOP state */ + ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_IN_LOOP); + + /* store the sngss7 ids */ + if (suInstId == 0) { + sngss7_info->suInstId = get_unique_id(); + } else { + sngss7_info->suInstId = suInstId; + } + sngss7_info->spInstId = spInstId; + sngss7_info->globalFlg = globalFlg; + + /* unlock the channel again before we exit */ + ftdm_mutex_unlock(ftdmchan->mutex); + + SS7_FUNC_TRACE_EXIT(__FUNCTION__); + return FTDM_SUCCESS; +} + +/******************************************************************************/ +ftdm_status_t handle_cot_stop(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, uint8_t globalFlg, uint8_t evntType, SiStaEvnt *siStaEvnt) +{ + SS7_FUNC_TRACE_ENTER(__FUNCTION__); + + sngss7_chan_data_t *sngss7_info = NULL; + ftdm_channel_t *ftdmchan = NULL; + + /* get the ftdmchan and ss7_chan_data from the circuit */ + if (extract_chan_data(circuit, &sngss7_info, &ftdmchan)) { + SS7_ERROR("Failed to extract channel data for circuit = %d!\n", circuit); + SS7_FUNC_TRACE_EXIT(__FUNCTION__); + return FTDM_FAIL; + } + + /* now that we have the right channel...put a lock on it so no-one else can use it */ + ftdm_mutex_lock(ftdmchan->mutex); + + /* check if there is a pending state change, give it a bit to clear */ + if (check_for_state_change(ftdmchan)) { + SS7_ERROR("Failed to wait for pending state change on CIC = %d\n", sngss7_info->circuit->cic); + ftdm_mutex_unlock(ftdmchan->mutex); + SS7_FUNC_TRACE_EXIT(__FUNCTION__); + SS7_ASSERT; + }; + + /* tell the core to stop looping the channel */ + ftdm_channel_command(ftdmchan, FTDM_COMMAND_DISABLE_LOOP, NULL); + + /* exit out of the LOOP state to the last state */ + ftdm_set_state_locked(ftdmchan, ftdmchan->last_state); + + /* unlock the channel again before we exit */ + ftdm_mutex_unlock(ftdmchan->mutex); + + SS7_FUNC_TRACE_EXIT(__FUNCTION__); + return FTDM_SUCCESS; +} + +/******************************************************************************/ +ftdm_status_t handle_cot(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, uint8_t globalFlg, uint8_t evntType, SiStaEvnt *siStaEvnt) +{ + SS7_FUNC_TRACE_ENTER(__FUNCTION__); + + if ( (siStaEvnt->contInd.eh.pres > 0) && (siStaEvnt->contInd.contInd.pres > 0)) { + SS7_INFO("Continuity Test result for CIC = %d (span %d, chan %d) is: \"%s\"\n", + g_ftdm_sngss7_data.cfg.isupCkt[circuit].cic, + g_ftdm_sngss7_data.cfg.isupCkt[circuit].span, + g_ftdm_sngss7_data.cfg.isupCkt[circuit].chan, + (siStaEvnt->contInd.contInd.val) ? "PASS" : "FAIL"); + } else { + SS7_ERROR("Recieved Continuity report containing no results!\n"); + } + + SS7_FUNC_TRACE_EXIT(__FUNCTION__); + return FTDM_SUCCESS; +} + +/******************************************************************************/ + + +/******************************************************************************/ +ftdm_status_t handle_blo_req(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, uint8_t globalFlg, uint8_t evntType, SiStaEvnt *siStaEvnt) +{ + SS7_FUNC_TRACE_ENTER(__FUNCTION__); + + sngss7_chan_data_t *sngss7_info = NULL; + ftdm_channel_t *ftdmchan = NULL; + + /* get the ftdmchan and ss7_chan_data from the circuit */ + if (extract_chan_data(circuit, &sngss7_info, &ftdmchan)) { + SS7_ERROR("Failed to extract channel data for circuit = %d!\n", circuit); + SS7_FUNC_TRACE_EXIT(__FUNCTION__); + return FTDM_FAIL; + } + + /* now that we have the right channel...put a lock on it so no-one else can use it */ + ftdm_mutex_lock(ftdmchan->mutex); + + /* check if there is a pending state change, give it a bit to clear */ + if (check_for_state_change(ftdmchan)) { + SS7_ERROR("Failed to wait for pending state change on CIC = %d\n", sngss7_info->circuit->cic); + ftdm_mutex_unlock(ftdmchan->mutex); + SS7_FUNC_TRACE_EXIT(__FUNCTION__); + SS7_ASSERT; + }; + + /* check if the circuit is already blocked or not */ + if (sngss7_test_flag(sngss7_info, FLAG_CKT_MN_BLOCK_RX)) { + SS7_WARN("Received BLO on circuit that is already blocked!\n"); + } + + /* throw the ckt block flag */ + sngss7_set_flag(sngss7_info, FLAG_CKT_MN_BLOCK_RX); + + /* set the channel to suspended state */ + ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_SUSPENDED); + + /* unlock the channel again before we exit */ + ftdm_mutex_unlock(ftdmchan->mutex); + + SS7_FUNC_TRACE_EXIT(__FUNCTION__); + return FTDM_SUCCESS; +} + +/******************************************************************************/ +ftdm_status_t handle_blo_rsp(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, uint8_t globalFlg, uint8_t evntType, SiStaEvnt *siStaEvnt) +{ + SS7_FUNC_TRACE_ENTER(__FUNCTION__); + + sngss7_chan_data_t *sngss7_info = NULL; + ftdm_channel_t *ftdmchan = NULL; + + /* get the ftdmchan and ss7_chan_data from the circuit */ + if (extract_chan_data(circuit, &sngss7_info, &ftdmchan)) { + SS7_ERROR("Failed to extract channel data for circuit = %d!\n", circuit); + SS7_FUNC_TRACE_EXIT(__FUNCTION__); + return FTDM_FAIL; + } + + /* now that we have the right channel...put a lock on it so no-one else can use it */ + ftdm_mutex_lock(ftdmchan->mutex); + + /* check if there is a pending state change, give it a bit to clear */ + if (check_for_state_change(ftdmchan)) { + SS7_ERROR("Failed to wait for pending state change on CIC = %d\n", sngss7_info->circuit->cic); + ftdm_mutex_unlock(ftdmchan->mutex); + SS7_FUNC_TRACE_EXIT(__FUNCTION__); + SS7_ASSERT; + }; + + /* KONRAD FIX ME */ + + /* unlock the channel again before we exit */ + ftdm_mutex_unlock(ftdmchan->mutex); + + SS7_FUNC_TRACE_EXIT(__FUNCTION__); + return FTDM_SUCCESS; +} + +/******************************************************************************/ +ftdm_status_t handle_ubl_req(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, uint8_t globalFlg, uint8_t evntType, SiStaEvnt *siStaEvnt) +{ + SS7_FUNC_TRACE_ENTER(__FUNCTION__); + + sngss7_chan_data_t *sngss7_info = NULL; + ftdm_channel_t *ftdmchan = NULL; + + /* get the ftdmchan and ss7_chan_data from the circuit */ + if (extract_chan_data(circuit, &sngss7_info, &ftdmchan)) { + SS7_ERROR("Failed to extract channel data for circuit = %d!\n", circuit); + SS7_FUNC_TRACE_EXIT(__FUNCTION__); + return FTDM_FAIL; + } + + /* now that we have the right channel...put a lock on it so no-one else can use it */ + ftdm_mutex_lock(ftdmchan->mutex); + + /* check if there is a pending state change, give it a bit to clear */ + if (check_for_state_change(ftdmchan)) { + SS7_ERROR("Failed to wait for pending state change on CIC = %d\n", sngss7_info->circuit->cic); + ftdm_mutex_unlock(ftdmchan->mutex); + SS7_FUNC_TRACE_EXIT(__FUNCTION__); + SS7_ASSERT; + }; + + /* check if the channel is blocked */ + if (!(sngss7_test_flag(sngss7_info, FLAG_CKT_MN_BLOCK_RX))) { + SS7_WARN("Received UBL on circuit that is not blocked!\n"); + } + + /* throw the unblock flag */ + sngss7_set_flag(sngss7_info, FLAG_CKT_MN_UNBLK_RX); + + /* clear the block flag */ + sngss7_clear_flag(sngss7_info, FLAG_CKT_MN_BLOCK_RX); + + /* set the channel to suspended state */ + ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_SUSPENDED); + + /* unlock the channel again before we exit */ + ftdm_mutex_unlock(ftdmchan->mutex); + + SS7_FUNC_TRACE_EXIT(__FUNCTION__); + return FTDM_SUCCESS; +} + +/******************************************************************************/ +ftdm_status_t handle_ubl_rsp(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, uint8_t globalFlg, uint8_t evntType, SiStaEvnt *siStaEvnt) +{ + SS7_FUNC_TRACE_ENTER(__FUNCTION__); + + sngss7_chan_data_t *sngss7_info = NULL; + ftdm_channel_t *ftdmchan = NULL; + + /* get the ftdmchan and ss7_chan_data from the circuit */ + if (extract_chan_data(circuit, &sngss7_info, &ftdmchan)) { + SS7_ERROR("Failed to extract channel data for circuit = %d!\n", circuit); + SS7_FUNC_TRACE_EXIT(__FUNCTION__); + return FTDM_FAIL; + } + + /* now that we have the right channel...put a lock on it so no-one else can use it */ + ftdm_mutex_lock(ftdmchan->mutex); + + /* check if there is a pending state change, give it a bit to clear */ + if (check_for_state_change(ftdmchan)) { + SS7_ERROR("Failed to wait for pending state change on CIC = %d\n", sngss7_info->circuit->cic); + ftdm_mutex_unlock(ftdmchan->mutex); + SS7_FUNC_TRACE_EXIT(__FUNCTION__); + SS7_ASSERT; + }; + + /* KONRAD FIX ME */ + + /* unlock the channel again before we exit */ + ftdm_mutex_unlock(ftdmchan->mutex); + + SS7_FUNC_TRACE_EXIT(__FUNCTION__); + return FTDM_SUCCESS; +} + +/******************************************************************************/ +ftdm_status_t handle_rsc_req(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, uint8_t globalFlg, uint8_t evntType, SiStaEvnt *siStaEvnt) +{ + SS7_FUNC_TRACE_ENTER(__FUNCTION__); + + sngss7_chan_data_t *sngss7_info = NULL; + ftdm_channel_t *ftdmchan = NULL; + + /* get the ftdmchan and ss7_chan_data from the circuit */ + if (extract_chan_data(circuit, &sngss7_info, &ftdmchan)) { + SS7_ERROR("Failed to extract channel data for circuit = %d!\n", circuit); + SS7_FUNC_TRACE_EXIT(__FUNCTION__); + return FTDM_FAIL; + } + + /* now that we have the right channel...put a lock on it so no-one else can use it */ + ftdm_mutex_lock(ftdmchan->mutex); + + /* check if there is a pending state change, give it a bit to clear */ + if (check_for_state_change(ftdmchan)) { + SS7_ERROR("Failed to wait for pending state change on CIC = %d\n", sngss7_info->circuit->cic); + ftdm_mutex_unlock(ftdmchan->mutex); + SS7_FUNC_TRACE_EXIT(__FUNCTION__); + SS7_ASSERT; + }; + + /* throw the reset flag */ + sngss7_set_flag(sngss7_info, FLAG_RESET_RX); + + switch (ftdmchan->state) { + /**************************************************************************/ + case FTDM_CHANNEL_STATE_RESTART: + + /* go to idle so that we can redo the restart state*/ + ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_IDLE); + + break; + /**************************************************************************/ + default: + + /* set the state of the channel to restart...the rest is done by the chan monitor */ + ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_RESTART); + break; + /**************************************************************************/ + } + + /* unlock the channel again before we exit */ + ftdm_mutex_unlock(ftdmchan->mutex); + + SS7_FUNC_TRACE_EXIT(__FUNCTION__); + return FTDM_SUCCESS; +} + +/******************************************************************************/ +ftdm_status_t handle_local_rsc_req(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, uint8_t globalFlg, uint8_t evntType, SiStaEvnt *siStaEvnt) +{ + SS7_FUNC_TRACE_ENTER(__FUNCTION__); + + sngss7_chan_data_t *sngss7_info = NULL; + ftdm_channel_t *ftdmchan = NULL; + + /* get the ftdmchan and ss7_chan_data from the circuit */ + if (extract_chan_data(circuit, &sngss7_info, &ftdmchan)) { + SS7_ERROR("Failed to extract channel data for circuit = %d!\n", circuit); + SS7_FUNC_TRACE_EXIT(__FUNCTION__); + return FTDM_FAIL; + } + + /* now that we have the right channel...put a lock on it so no-one else can use it */ + ftdm_mutex_lock(ftdmchan->mutex); + + /* check if there is a pending state change, give it a bit to clear */ + if (check_for_state_change(ftdmchan)) { + SS7_ERROR("Failed to wait for pending state change on CIC = %d\n", sngss7_info->circuit->cic); + ftdm_mutex_unlock(ftdmchan->mutex); + SS7_FUNC_TRACE_EXIT(__FUNCTION__); + SS7_ASSERT; + }; + + /* throw the reset flag */ + sngss7_set_flag(sngss7_info, FLAG_RESET_RX); + + switch (ftdmchan->state) { + /**************************************************************************/ + case FTDM_CHANNEL_STATE_RESTART: + + /* go to idle so that we can redo the restart state*/ + ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_IDLE); + + break; + /**************************************************************************/ + default: + + /* set the state of the channel to restart...the rest is done by the chan monitor */ + ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_RESTART); + break; + /**************************************************************************/ + } + + /* unlock the channel again before we exit */ + ftdm_mutex_unlock(ftdmchan->mutex); + + SS7_FUNC_TRACE_EXIT(__FUNCTION__); + return FTDM_SUCCESS; +} + +/******************************************************************************/ +ftdm_status_t handle_rsc_rsp(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, uint8_t globalFlg, uint8_t evntType, SiStaEvnt *siStaEvnt) +{ + SS7_FUNC_TRACE_ENTER(__FUNCTION__); + + sngss7_chan_data_t *sngss7_info = NULL; + ftdm_channel_t *ftdmchan = NULL; + + /* get the ftdmchan and ss7_chan_data from the circuit */ + if (extract_chan_data(circuit, &sngss7_info, &ftdmchan)) { + SS7_ERROR("Failed to extract channel data for circuit = %d!\n", circuit); + SS7_FUNC_TRACE_EXIT(__FUNCTION__); + return FTDM_FAIL; + } + + /* now that we have the right channel...put a lock on it so no-one else can use it */ + ftdm_mutex_lock(ftdmchan->mutex); + + /* check if there is a pending state change, give it a bit to clear */ + if (check_for_state_change(ftdmchan)) { + SS7_ERROR("Failed to wait for pending state change on CIC = %d\n", sngss7_info->circuit->cic); + ftdm_mutex_unlock(ftdmchan->mutex); + SS7_FUNC_TRACE_EXIT(__FUNCTION__); + SS7_ASSERT; + }; + + switch (ftdmchan->state) { + /**********************************************************************/ + case FTDM_CHANNEL_STATE_RESTART: + + if ( sngss7_test_flag(sngss7_info, FLAG_RESET_TX) ) { + /* throw the FLAG_RESET_TX_RSP to indicate we have acknowledgement from the remote side */ + sngss7_set_flag(sngss7_info, FLAG_RESET_TX_RSP); + + /* go to DOWN */ + ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_DOWN); + } else { + SS7_ERROR("Received RSC-RLC but we're not waiting on a RSC-RLC on CIC #, dropping\n", sngss7_info->circuit->cic); + } + + break; + /**********************************************************************/ + case FTDM_CHANNEL_STATE_DOWN: + + /* do nothing, just drop the message */ + SS7_DEBUG("Receveived RSC-RLC in down state, dropping\n"); + + break; + /**********************************************************************/ + case FTDM_CHANNEL_STATE_TERMINATING: + case FTDM_CHANNEL_STATE_HANGUP: + case FTDM_CHANNEL_STATE_HANGUP_COMPLETE: + + /* throw the FLAG_RESET_TX_RSP to indicate we have acknowledgement from the remote side */ + sngss7_set_flag(sngss7_info, FLAG_RESET_TX_RSP); + + /* go to DOWN */ + ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_DOWN); + + break; + /**********************************************************************/ + default: + /* ITU Q764-2.9.5.1.c -> release the circuit */ + if ((siStaEvnt != NULL) && + (siStaEvnt->causeDgn.eh.pres ==PRSNT_NODEF) && + (siStaEvnt->causeDgn.causeVal.pres == PRSNT_NODEF)) { + ftdmchan->caller_data.hangup_cause = siStaEvnt->causeDgn.causeVal.val; + } else { + ftdmchan->caller_data.hangup_cause = 98; /* Message not compatiable with call state */ + } + + ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_TERMINATING); + break; + /**********************************************************************/ + } + + /* unlock the channel again before we exit */ + ftdm_mutex_unlock(ftdmchan->mutex); + + SS7_FUNC_TRACE_EXIT(__FUNCTION__); + return FTDM_SUCCESS; +} +/******************************************************************************/ +ftdm_status_t handle_grs_req(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, uint8_t globalFlg, uint8_t evntType, SiStaEvnt *siStaEvnt) +{ + SS7_FUNC_TRACE_ENTER(__FUNCTION__); + + sngss7_chan_data_t *sngss7_info = NULL; + ftdm_channel_t *ftdmchan = NULL; + sngss7_span_data_t *span = NULL; + int range; + int x; + + if (extract_chan_data(circuit, &sngss7_info, &ftdmchan)) { + SS7_ERROR("Failed to extract channel data for circuit = %d!\n", circuit); + SS7_FUNC_TRACE_EXIT(__FUNCTION__); + return FTDM_FAIL; + } + + /* extract the range value from the event structure */ + if ((siStaEvnt->rangStat.eh.pres == PRSNT_NODEF) && (siStaEvnt->rangStat.range.pres == PRSNT_NODEF)) { + range = siStaEvnt->rangStat.range.val; + } else { + SS7_ERROR("Received GRS with no range value on CIC = %d\n", sngss7_info->circuit->cic); + SS7_FUNC_TRACE_EXIT(__FUNCTION__); + return FTDM_FAIL; + } + + /* loop over the cics starting from circuit until range+1 */ + for (x = circuit; x < (circuit + range + 1); x++) { + /* grab the circuit in question */ + if (extract_chan_data(x, &sngss7_info, &ftdmchan)) { + SS7_ERROR("Failed to extract channel data for circuit = %d!\n", x); + break; + } + + /* now that we have the right channel...put a lock on it so no-one else can use it */ + ftdm_mutex_lock(ftdmchan->mutex); + + /* check if there is a pending state change, give it a bit to clear */ + if (check_for_state_change(ftdmchan)) { + SS7_ERROR("Failed to wait for pending state change on CIC = %d\n", sngss7_info->circuit->cic); + ftdm_mutex_unlock(ftdmchan->mutex); + SS7_ASSERT; + }; + + /* fill in the span structure for this circuit */ + span = ftdmchan->span->mod_data; + span->grs.circuit = circuit; + span->grs.range = range; + + SS7_DEBUG_CHAN(ftdmchan, "Rx GRS (%d:%d)\n", + g_ftdm_sngss7_data.cfg.isupCkt[circuit].cic, + (g_ftdm_sngss7_data.cfg.isupCkt[circuit].cic + range)); + + /* flag the channel as having received a reset */ + sngss7_set_flag(sngss7_info, FLAG_GRP_RESET_RX); + + switch (ftdmchan->state) { + /**************************************************************************/ + case FTDM_CHANNEL_STATE_RESTART: + + /* go to idle so that we can redo the restart state*/ + ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_IDLE); + + break; + /**************************************************************************/ + default: + + /* set the state of the channel to restart...the rest is done by the chan monitor */ + ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_RESTART); + break; + /**************************************************************************/ + } + + /* unlock the channel again before we exit */ + ftdm_mutex_unlock(ftdmchan->mutex); + + } + + SS7_FUNC_TRACE_EXIT(__FUNCTION__); + return FTDM_SUCCESS; +} + +/******************************************************************************/ +ftdm_status_t handle_grs_rsp(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, uint8_t globalFlg, uint8_t evntType, SiStaEvnt *siStaEvnt) +{ + SS7_FUNC_TRACE_ENTER(__FUNCTION__); + + sngss7_chan_data_t *sngss7_info = NULL; + ftdm_channel_t *ftdmchan = NULL; + int range; + int x; + + /* extract the range value from the event structure */ + if ((siStaEvnt->rangStat.eh.pres == PRSNT_NODEF) && (siStaEvnt->rangStat.range.pres == PRSNT_NODEF)) { + range = siStaEvnt->rangStat.range.val; + } else { + SS7_ERROR("Received GRA with no range value on CIC = %d\n", sngss7_info->circuit->cic); + SS7_FUNC_TRACE_EXIT(__FUNCTION__); + return FTDM_FAIL; + } + + /* go through all the circuits in the range */ + for ( x = circuit; x < (circuit + range + 1); x++) { + + /* grab the circuit in question */ + if (extract_chan_data(x, &sngss7_info, &ftdmchan)) { + SS7_ERROR("Failed to extract channel data for circuit = %d!\n", circuit); + break; + } + + /* now that we have the right channel...put a lock on it so no-one else can use it */ + ftdm_mutex_lock(ftdmchan->mutex); + + /* check if there is a pending state change, give it a bit to clear */ + if (check_for_state_change(ftdmchan)) { + SS7_ERROR("Failed to wait for pending state change on CIC = %d\n", sngss7_info->circuit->cic); + ftdm_mutex_unlock(ftdmchan->mutex); + SS7_ASSERT; + }; + + SS7_DEBUG_CHAN(ftdmchan, "Rx GRA (%d:%d)\n", + g_ftdm_sngss7_data.cfg.isupCkt[circuit].cic, + (g_ftdm_sngss7_data.cfg.isupCkt[circuit].cic + range)); + + switch (ftdmchan->state) { + /**********************************************************************/ + case FTDM_CHANNEL_STATE_RESTART: + + /* throw the FLAG_RESET_TX_RSP to indicate we have acknowledgement from the remote side */ + sngss7_set_flag(sngss7_info, FLAG_GRP_RESET_TX_RSP); + + /* go to DOWN */ + ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_DOWN); + + break; + /**********************************************************************/ + case FTDM_CHANNEL_STATE_DOWN: + + /* do nothing, just drop the message */ + SS7_DEBUG("Receveived GRA in down state, dropping\n"); + + break; + /**********************************************************************/ + case FTDM_CHANNEL_STATE_TERMINATING: + case FTDM_CHANNEL_STATE_HANGUP: + case FTDM_CHANNEL_STATE_HANGUP_COMPLETE: + + /* throw the FLAG_RESET_TX_RSP to indicate we have acknowledgement from the remote side */ + sngss7_set_flag(sngss7_info, FLAG_GRP_RESET_TX_RSP); + + break; + /**********************************************************************/ + default: + /* ITU Q764-2.9.5.1.c -> release the circuit */ + if ((siStaEvnt != NULL) && + (siStaEvnt->causeDgn.eh.pres ==PRSNT_NODEF) && + (siStaEvnt->causeDgn.causeVal.pres == PRSNT_NODEF)) { + ftdmchan->caller_data.hangup_cause = siStaEvnt->causeDgn.causeVal.val; + } else { + ftdmchan->caller_data.hangup_cause = 98; /* Message not compatiable with call state */ + } + + /* go to terminating to hang up the call */ + ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_TERMINATING); + break; + /**********************************************************************/ + } + + /* unlock the channel again before we exit */ + ftdm_mutex_unlock(ftdmchan->mutex); + + } /* for (( x = 0; x < (circuit + range); x++) */ + + SS7_FUNC_TRACE_EXIT(__FUNCTION__); + return FTDM_SUCCESS; +} + +/******************************************************************************/ +ftdm_status_t handle_local_blk(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, uint8_t globalFlg, uint8_t evntType, SiStaEvnt *siStaEvnt) +{ + SS7_FUNC_TRACE_ENTER(__FUNCTION__); + + sngss7_chan_data_t *sngss7_info = NULL; + ftdm_channel_t *ftdmchan = NULL; + + /* get the ftdmchan and ss7_chan_data from the circuit */ + if (extract_chan_data(circuit, &sngss7_info, &ftdmchan)) { + SS7_ERROR("Failed to extract channel data for circuit = %d!\n", circuit); + SS7_FUNC_TRACE_EXIT(__FUNCTION__); + return FTDM_FAIL; + } + + /* now that we have the right channel...put a lock on it so no-one else can use it */ + ftdm_mutex_lock(ftdmchan->mutex); + + /* check if there is a pending state change, give it a bit to clear */ + if (check_for_state_change(ftdmchan)) { + SS7_ERROR("Failed to wait for pending state change on CIC = %d\n", sngss7_info->circuit->cic); + ftdm_mutex_unlock(ftdmchan->mutex); + SS7_FUNC_TRACE_EXIT(__FUNCTION__); + SS7_ASSERT; + }; + + /* check if the circuit is already blocked or not */ + if (sngss7_test_flag(sngss7_info, FLAG_CKT_LC_BLOCK_RX)) { + SS7_WARN("Received local BLO on circuit that is already blocked!\n"); + } + + /* throw the ckt block flag */ + sngss7_set_flag(sngss7_info, FLAG_CKT_LC_BLOCK_RX); + + /* set the channel to suspended state */ + ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_SUSPENDED); + + /* unlock the channel again before we exit */ + ftdm_mutex_unlock(ftdmchan->mutex); + + SS7_FUNC_TRACE_EXIT(__FUNCTION__); + return FTDM_SUCCESS; +} + +/******************************************************************************/ +ftdm_status_t handle_local_ubl(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, uint8_t globalFlg, uint8_t evntType, SiStaEvnt *siStaEvnt) +{ + SS7_FUNC_TRACE_ENTER(__FUNCTION__); + + sngss7_chan_data_t *sngss7_info = NULL; + ftdm_channel_t *ftdmchan = NULL; + + /* get the ftdmchan and ss7_chan_data from the circuit */ + if (extract_chan_data(circuit, &sngss7_info, &ftdmchan)) { + SS7_ERROR("Failed to extract channel data for circuit = %d!\n", circuit); + SS7_FUNC_TRACE_EXIT(__FUNCTION__); + return FTDM_FAIL; + } + + /* now that we have the right channel...put a lock on it so no-one else can use it */ + ftdm_mutex_lock(ftdmchan->mutex); + + /* check if there is a pending state change, give it a bit to clear */ + if (check_for_state_change(ftdmchan)) { + SS7_ERROR("Failed to wait for pending state change on CIC = %d\n", sngss7_info->circuit->cic); + ftdm_mutex_unlock(ftdmchan->mutex); + SS7_FUNC_TRACE_EXIT(__FUNCTION__); + SS7_ASSERT; + }; + + /* check if the circuit is already blocked or not */ + if (sngss7_test_flag(sngss7_info, FLAG_CKT_LC_UNBLK_RX)) { + SS7_WARN("Received local UBL on circuit that is already unblocked!\n"); + } + + /* throw the ckt block flag */ + sngss7_set_flag(sngss7_info, FLAG_CKT_LC_UNBLK_RX); + + /* set the channel to suspended state */ + ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_SUSPENDED); + + /* unlock the channel again before we exit */ + ftdm_mutex_unlock(ftdmchan->mutex); + + SS7_FUNC_TRACE_EXIT(__FUNCTION__); + return FTDM_SUCCESS; +} + +/******************************************************************************/ +ftdm_status_t handle_ucic(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, uint8_t globalFlg, uint8_t evntType, SiStaEvnt *siStaEvnt) +{ + SS7_FUNC_TRACE_ENTER(__FUNCTION__); + + sngss7_chan_data_t *sngss7_info = NULL; + ftdm_channel_t *ftdmchan = NULL; + + /* get the ftdmchan and ss7_chan_data from the circuit */ + if (extract_chan_data(circuit, &sngss7_info, &ftdmchan)) { + SS7_ERROR("Failed to extract channel data for circuit = %d!\n", circuit); + SS7_FUNC_TRACE_EXIT(__FUNCTION__); + return FTDM_FAIL; + } + + /* now that we have the right channel...put a lock on it so no-one else can use it */ + ftdm_mutex_lock(ftdmchan->mutex); + + /* check if there is a pending state change, give it a bit to clear */ + if (check_for_state_change(ftdmchan)) { + SS7_ERROR("Failed to wait for pending state change on CIC = %d\n", sngss7_info->circuit->cic); + ftdm_mutex_unlock(ftdmchan->mutex); + SS7_FUNC_TRACE_EXIT(__FUNCTION__); + SS7_ASSERT; + }; + + /* throw the ckt block flag */ + sngss7_set_flag(sngss7_info, FLAG_CKT_UCIC_BLOCK); + + /* set the channel to suspended state */ + ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_SUSPENDED); + + /* unlock the channel again before we exit */ + ftdm_mutex_unlock(ftdmchan->mutex); + + SS7_FUNC_TRACE_EXIT(__FUNCTION__); + return FTDM_SUCCESS; +} + + +/******************************************************************************/ +/* For Emacs: + * Local Variables: + * mode:c + * indent-tabs-mode:t + * tab-width:4 + * c-basic-offset:4 + * End: + * For VIM: + * vim:set softtabstop=4 shiftwidth=4 tabstop=4: + */ +/******************************************************************************/ diff --git a/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_in.c b/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_in.c index 98554db6a4..34893cf5aa 100644 --- a/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_in.c +++ b/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_in.c @@ -53,31 +53,6 @@ void sngss7_fac_ind(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, uint void sngss7_fac_cfm(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, uint8_t evntType, SiFacEvnt *siFacEvnt); void sngss7_umsg_ind(uint32_t suInstId, uint32_t spInstId, uint32_t circuit); -static ftdm_status_t handle_reattempt(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, uint8_t globalFlg, uint8_t evntType, SiStaEvnt *siStaEvnt); -static ftdm_status_t handle_pause(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, uint8_t globalFlg, uint8_t evntType, SiStaEvnt *siStaEvnt); -static ftdm_status_t handle_resume(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, uint8_t globalFlg, uint8_t evntType, SiStaEvnt *siStaEvnt); - -static ftdm_status_t handle_cot_start(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, uint8_t globalFlg, uint8_t evntType, SiStaEvnt *siStaEvnt); -static ftdm_status_t handle_cot_stop(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, uint8_t globalFlg, uint8_t evntType, SiStaEvnt *siStaEvnt); -static ftdm_status_t handle_cot(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, uint8_t globalFlg, uint8_t evntType, SiStaEvnt *siStaEvnt); - -static ftdm_status_t handle_rsc_req(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, uint8_t globalFlg, uint8_t evntType, SiStaEvnt *siStaEvnt); -static ftdm_status_t handle_local_rsc_req(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, uint8_t globalFlg, uint8_t evntType, SiStaEvnt *siStaEvnt); -static ftdm_status_t handle_rsc_rsp(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, uint8_t globalFlg, uint8_t evntType, SiStaEvnt *siStaEvnt); - -static ftdm_status_t handle_grs_req(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, uint8_t globalFlg, uint8_t evntType, SiStaEvnt *siStaEvnt); -static ftdm_status_t handle_grs_rsp(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, uint8_t globalFlg, uint8_t evntType, SiStaEvnt *siStaEvnt); - -static ftdm_status_t handle_blo_req(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, uint8_t globalFlg, uint8_t evntType, SiStaEvnt *siStaEvnt); -static ftdm_status_t handle_blo_rsp(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, uint8_t globalFlg, uint8_t evntType, SiStaEvnt *siStaEvnt); -static ftdm_status_t handle_ubl_req(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, uint8_t globalFlg, uint8_t evntType, SiStaEvnt *siStaEvnt); -static ftdm_status_t handle_ubl_rsp(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, uint8_t globalFlg, uint8_t evntType, SiStaEvnt *siStaEvnt); - -static ftdm_status_t handle_local_blk(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, uint8_t globalFlg, uint8_t evntType, SiStaEvnt *siStaEvnt); -static ftdm_status_t handle_local_ubl(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, uint8_t globalFlg, uint8_t evntType, SiStaEvnt *siStaEvnt); - -static ftdm_status_t handle_ucic(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, uint8_t globalFlg, uint8_t evntType, SiStaEvnt *siStaEvnt); - /******************************************************************************/ /* FUNCTIONS ******************************************************************/ @@ -85,8 +60,9 @@ void sngss7_con_ind(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, SiCo { SS7_FUNC_TRACE_ENTER(__FUNCTION__); - sngss7_chan_data_t *sngss7_info ; - ftdm_channel_t *ftdmchan; + sngss7_chan_data_t *sngss7_info = NULL; + ftdm_channel_t *ftdmchan = NULL; + sngss7_event_data_t *sngss7_event = NULL; /* get the ftdmchan and ss7_chan_data from the circuit */ if (extract_chan_data(circuit, &sngss7_info, &ftdmchan)) { @@ -95,119 +71,26 @@ void sngss7_con_ind(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, SiCo return; } - /* now that we have the right channel...put a lock on it so no-one else can use it */ - ftdm_mutex_lock(ftdmchan->mutex); - - /* check if there is a pending state change, give it a bit to clear */ - if (check_for_state_change(ftdmchan)) { - SS7_ERROR("Failed to wait for pending state change on CIC = %d\n", sngss7_info->circuit->cic); - ftdm_mutex_unlock(ftdmchan->mutex); + /* initalize the sngss7_event */ + sngss7_event = ftdm_malloc(sizeof(*sngss7_event)); + if (sngss7_event == NULL) { + SS7_ERROR("Failed to allocate memory for sngss7_event!\n"); SS7_FUNC_TRACE_EXIT(__FUNCTION__); - SS7_ASSERT; - }; - - SS7_MSG_TRACE(ftdmchan, sngss7_info, "Rx IAM\n"); - - /* check if the circuit has a remote block */ - if ((sngss7_test_flag(sngss7_info, FLAG_CKT_MN_BLOCK_RX)) || - (sngss7_test_flag(sngss7_info, FLAG_GRP_HW_BLOCK_RX)) || - (sngss7_test_flag(sngss7_info, FLAG_GRP_MN_BLOCK_RX))) { - - /* as per Q.764, 2.8.2.3 xiv ... remove the block from this channel */ - sngss7_clear_flag(sngss7_info, FLAG_CKT_MN_BLOCK_RX); - sngss7_clear_flag(sngss7_info, FLAG_GRP_HW_BLOCK_RX); - sngss7_clear_flag(sngss7_info, FLAG_GRP_MN_BLOCK_RX); - - /* KONRAD FIX ME : check in case there is a ckt and grp block */ + return; } + memset(sngss7_event, 0x0, sizeof(*sngss7_event)); - /* check whether the ftdm channel is in a state to accept a call */ - switch (ftdmchan->state) { - /**************************************************************************/ - case (FTDM_CHANNEL_STATE_DOWN): /* only state it is fully valid to get IAM */ + /* fill in the sngss7_event struct */ + sngss7_event->spInstId = spInstId; + sngss7_event->suInstId = suInstId; + sngss7_event->circuit = circuit; + sngss7_event->event_id = SNGSS7_CON_IND_EVENT; + memcpy(&sngss7_event->event.siConEvnt, siConEvnt, sizeof(*siConEvnt)); - /* fill in the channels SS7 Stack information */ - sngss7_info->suInstId = get_unique_id(); - sngss7_info->spInstId = spInstId; - - /* try to open the ftdm channel */ - if (ftdm_channel_open_chan(ftdmchan) != FTDM_SUCCESS) { - SS7_ERROR("Failed to open span: %d, chan: %d\n", - ftdmchan->physical_span_id, - ftdmchan->physical_chan_id); - - /* set the flag to indicate this hangup is started from the local side */ - sngss7_set_flag(sngss7_info, FLAG_LOCAL_REL); - - ftdmchan->caller_data.hangup_cause = 41; - - /* move the state to CANCEL */ - ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_CANCEL); - - } else { - - /* fill in cid/ani number */ - if (siConEvnt->cgPtyNum.addrSig.pres) { - copy_tknStr_from_sngss7(siConEvnt->cgPtyNum.addrSig, - ftdmchan->caller_data.cid_num.digits, - siConEvnt->cgPtyNum.oddEven); - - /* fill in cid Name */ - ftdm_set_string(ftdmchan->caller_data.cid_name, ftdmchan->caller_data.cid_num.digits); - - ftdm_set_string(ftdmchan->caller_data.ani.digits, ftdmchan->caller_data.cid_num.digits); - - } else { - SS7_INFO("No Calling party (ANI) information in IAM!\n"); - } - - /* fill in dnis */ - if (siConEvnt->cdPtyNum.addrSig.pres) { - copy_tknStr_from_sngss7(siConEvnt->cdPtyNum.addrSig, - ftdmchan->caller_data.dnis.digits, - siConEvnt->cdPtyNum.oddEven); - } else { - SS7_INFO("No Called party (DNIS) information in IAM!\n"); - } - - /* fill in rdnis */ - if (siConEvnt->redirgNum.addrSig.pres) { - copy_tknStr_from_sngss7(siConEvnt->redirgNum.addrSig, - ftdmchan->caller_data.rdnis.digits, - siConEvnt->cgPtyNum.oddEven); - } else { - SS7_INFO("No RDNIS party information in IAM!\n"); - } - - /* fill in screening/presentation */ - ftdmchan->caller_data.screen = siConEvnt->cgPtyNum.scrnInd.val; - ftdmchan->caller_data.pres = siConEvnt->cgPtyNum.presRest.val; - - /* set the state of the channel to collecting...the rest is done by the chan monitor */ - ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_COLLECT); - - } /* if (ftdm_channel_open_chan(ftdmchan) != FTDM_SUCCESS) */ - - break; - /**************************************************************************/ - default: /* should not have gotten an IAM while in this state */ - SS7_ERROR("Got IAM in an invalid state (%s) on span=%d, chan=%d!\n", - ftdm_channel_state2str(ftdmchan->state), - ftdmchan->physical_span_id, - ftdmchan->physical_chan_id); - - /* move the state of the channel to RESTART to force a reset */ - ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_RESTART); - - break; - /**************************************************************************/ - } /* switch (ftdmchan->state) */ - - /* unlock the channel */ - ftdm_mutex_unlock(ftdmchan->mutex); + /* enqueue this event */ + ftdm_queue_enqueue(((sngss7_span_data_t*)sngss7_info->ftdmchan->span->mod_data)->event_queue, sngss7_event); SS7_FUNC_TRACE_EXIT(__FUNCTION__); - return; } /******************************************************************************/ @@ -215,8 +98,9 @@ void sngss7_con_cfm(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, SiCo { SS7_FUNC_TRACE_ENTER(__FUNCTION__); - sngss7_chan_data_t *sngss7_info ; - ftdm_channel_t *ftdmchan; + sngss7_chan_data_t *sngss7_info = NULL; + ftdm_channel_t *ftdmchan = NULL; + sngss7_event_data_t *sngss7_event = NULL; /* get the ftdmchan and ss7_chan_data from the circuit */ if (extract_chan_data(circuit, &sngss7_info, &ftdmchan)) { @@ -225,59 +109,26 @@ void sngss7_con_cfm(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, SiCo return; } - /* now that we have the right channel...put a lock on it so no-one else can use it */ - ftdm_mutex_lock(ftdmchan->mutex); - - /* check if there is a pending state change, give it a bit to clear */ - if (check_for_state_change(ftdmchan)) { - SS7_ERROR("Failed to wait for pending state change on CIC = %d\n", sngss7_info->circuit->cic); - ftdm_mutex_unlock(ftdmchan->mutex); + /* initalize the sngss7_event */ + sngss7_event = ftdm_malloc(sizeof(*sngss7_event)); + if (sngss7_event == NULL) { + SS7_ERROR("Failed to allocate memory for sngss7_event!\n"); SS7_FUNC_TRACE_EXIT(__FUNCTION__); - SS7_ASSERT; - }; - - - /* check whether the ftdm channel is in a state to accept a call */ - switch (ftdmchan->state) { - /**************************************************************************/ - case FTDM_CHANNEL_STATE_PROGRESS: - case FTDM_CHANNEL_STATE_PROGRESS_MEDIA: - - SS7_MSG_TRACE(ftdmchan, sngss7_info, "Rx ANM\n"); - - /* go to UP */ - ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_UP); - - break; - /**************************************************************************/ - case FTDM_CHANNEL_STATE_DIALING: - - SS7_MSG_TRACE(ftdmchan, sngss7_info, "Rx CON\n"); - - /* go to UP */ - ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_UP); - - break; - /**************************************************************************/ - default: /* incorrect state...reset the CIC */ - - SS7_MSG_TRACE(ftdmchan, sngss7_info, "Rx ANM/CON\n"); - - /* throw the TX reset flag */ - sngss7_set_flag(sngss7_info, FLAG_GRP_RESET_TX); - - /* go to RESTART */ - ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_RESTART); - - break; - /**************************************************************************/ + return; } + memset(sngss7_event, 0x0, sizeof(*sngss7_event)); - /* unlock the channel */ - ftdm_mutex_unlock(ftdmchan->mutex); + /* fill in the sngss7_event struct */ + sngss7_event->spInstId = spInstId; + sngss7_event->suInstId = suInstId; + sngss7_event->circuit = circuit; + sngss7_event->event_id = SNGSS7_CON_CFM_EVENT; + memcpy(&sngss7_event->event.siConEvnt, siConEvnt, sizeof(*siConEvnt)); + + /* enqueue this event */ + ftdm_queue_enqueue(((sngss7_span_data_t*)sngss7_info->ftdmchan->span->mod_data)->event_queue, sngss7_event); SS7_FUNC_TRACE_EXIT(__FUNCTION__); - return; } /******************************************************************************/ @@ -285,8 +136,9 @@ void sngss7_con_sta(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, SiCn { SS7_FUNC_TRACE_ENTER(__FUNCTION__); - sngss7_chan_data_t *sngss7_info ; - ftdm_channel_t *ftdmchan; + sngss7_chan_data_t *sngss7_info = NULL; + ftdm_channel_t *ftdmchan = NULL; + sngss7_event_data_t *sngss7_event = NULL; /* get the ftdmchan and ss7_chan_data from the circuit */ if (extract_chan_data(circuit, &sngss7_info, &ftdmchan)) { @@ -295,159 +147,27 @@ void sngss7_con_sta(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, SiCn return; } - /* now that we have the right channel...put a lock on it so no-one else can use it */ - ftdm_mutex_lock(ftdmchan->mutex); - - /* check if there is a pending state change, give it a bit to clear */ - if (check_for_state_change(ftdmchan)) { - SS7_ERROR("Failed to wait for pending state change on CIC = %d\n", sngss7_info->circuit->cic); - ftdm_mutex_unlock(ftdmchan->mutex); + /* initalize the sngss7_event */ + sngss7_event = ftdm_malloc(sizeof(*sngss7_event)); + if (sngss7_event == NULL) { + SS7_ERROR("Failed to allocate memory for sngss7_event!\n"); SS7_FUNC_TRACE_EXIT(__FUNCTION__); - SS7_ASSERT; + return; } + memset(sngss7_event, 0x0, sizeof(*sngss7_event)); - switch (evntType) { - /**************************************************************************/ - case (ADDRCMPLT): - SS7_MSG_TRACE(ftdmchan, sngss7_info, "Rx ACM\n"); - switch (ftdmchan->state) { - /**********************************************************************/ - case FTDM_CHANNEL_STATE_DIALING: - /* KONRAD: should we confirm the instance ids ? */ + /* fill in the sngss7_event struct */ + sngss7_event->spInstId = spInstId; + sngss7_event->suInstId = suInstId; + sngss7_event->circuit = circuit; + sngss7_event->evntType = evntType; + sngss7_event->event_id = SNGSS7_CON_STA_EVENT; + memcpy(&sngss7_event->event.siCnStEvnt, siCnStEvnt, sizeof(*siCnStEvnt)); - /* need to grab the sp instance id */ - sngss7_info->spInstId = spInstId; - - /* go to PROGRESS */ - ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_PROGRESS); - break; - /**********************************************************************/ - default: /* incorrect state...reset the CIC */ - /* go to RESTART */ - ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_PROGRESS); - break; - /**********************************************************************/ - } /* switch (ftdmchan->state) */ - /**************************************************************************/ - case (MODIFY): - SS7_MSG_TRACE(ftdmchan, sngss7_info, "Rx MODIFY\n"); - break; - /**************************************************************************/ - case (MODCMPLT): - SS7_MSG_TRACE(ftdmchan, sngss7_info, "Rx MODIFY-COMPLETE\n"); - break; - /**************************************************************************/ - case (MODREJ): - SS7_MSG_TRACE(ftdmchan, sngss7_info, "Rx MODIFY-REJECT\n"); - break; - /**************************************************************************/ - case (PROGRESS): - SS7_MSG_TRACE(ftdmchan, sngss7_info, "Rx CPG\n"); - break; - /**************************************************************************/ - case (FRWDTRSFR): - SS7_MSG_TRACE(ftdmchan, sngss7_info, "Rx FOT\n"); - break; - /**************************************************************************/ - case (INFORMATION): - SS7_MSG_TRACE(ftdmchan, sngss7_info, "Rx INF\n"); - break; - /**************************************************************************/ - case (INFORMATREQ): - SS7_MSG_TRACE(ftdmchan, sngss7_info, "Rx INR\n"); - break; - /**************************************************************************/ - case (SUBSADDR): - SS7_MSG_TRACE(ftdmchan, sngss7_info, "Rx SAM\n"); - break; - /**************************************************************************/ - case (EXIT): - SS7_MSG_TRACE(ftdmchan, sngss7_info, "Rx EXIT\n"); - break; - /**************************************************************************/ - case (NETRESMGT): - SS7_MSG_TRACE(ftdmchan, sngss7_info, "Rx NRM\n"); - break; - /**************************************************************************/ - case (IDENTREQ): - SS7_MSG_TRACE(ftdmchan, sngss7_info, "Rx IDR\n"); - break; - /**************************************************************************/ - case (IDENTRSP): - SS7_MSG_TRACE(ftdmchan, sngss7_info, "Rx IRS\n"); - break; - /**************************************************************************/ - case (MALCLLPRNT): - SS7_MSG_TRACE(ftdmchan, sngss7_info, "Rx MALICIOUS CALL\n"); - break; - /**************************************************************************/ - case (CHARGE): - SS7_MSG_TRACE(ftdmchan, sngss7_info, "Rx CRG\n"); - break; - /**************************************************************************/ - case (TRFFCHGE): - SS7_MSG_TRACE(ftdmchan, sngss7_info, "Rx CRG-TARIFF\n"); - break; - /**************************************************************************/ - case (CHARGEACK): - SS7_MSG_TRACE(ftdmchan, sngss7_info, "Rx CRG-ACK\n"); - break; - /**************************************************************************/ - case (CALLOFFMSG): - SS7_MSG_TRACE(ftdmchan, sngss7_info, "Rx CALL-OFFER\n"); - break; - /**************************************************************************/ - case (LOOPPRVNT): - SS7_MSG_TRACE(ftdmchan, sngss7_info, "Rx LOP\n"); - break; - /**************************************************************************/ - case (TECT_TIMEOUT): - SS7_MSG_TRACE(ftdmchan, sngss7_info, "Rx ECT-Timeout\n"); - break; - /**************************************************************************/ - case (RINGSEND): - SS7_MSG_TRACE(ftdmchan, sngss7_info, "Rx RINGING-SEND\n"); - break; - /**************************************************************************/ - case (CALLCLEAR): - SS7_MSG_TRACE(ftdmchan, sngss7_info, "Rx CALL-LINE Clear\n"); - break; - /**************************************************************************/ - case (PRERELEASE): - SS7_MSG_TRACE(ftdmchan, sngss7_info, "Rx PRI\n"); - break; - /**************************************************************************/ - case (APPTRANSPORT): - SS7_MSG_TRACE(ftdmchan, sngss7_info, "Rx APM\n"); - break; - /**************************************************************************/ - case (OPERATOR): - SS7_MSG_TRACE(ftdmchan, sngss7_info, "Rx OPERATOR\n"); - break; - /**************************************************************************/ - case (METPULSE): - SS7_MSG_TRACE(ftdmchan, sngss7_info, "Rx METERING-PULSE\n"); - break; - /**************************************************************************/ - case (CLGPTCLR): - SS7_MSG_TRACE(ftdmchan, sngss7_info, "Rx CALLING_PARTY_CLEAR\n"); - break; - /**************************************************************************/ - case (SUBDIRNUM): - SS7_MSG_TRACE(ftdmchan, sngss7_info, "Rx SUB-DIR\n"); - break; - /**************************************************************************/ - default: - SS7_MSG_TRACE(ftdmchan, sngss7_info, "Rx Unknown Msg\n"); - break; - /**************************************************************************/ - } - - /* unlock the channel */ - ftdm_mutex_unlock(ftdmchan->mutex); + /* enqueue this event */ + ftdm_queue_enqueue(((sngss7_span_data_t*)sngss7_info->ftdmchan->span->mod_data)->event_queue, sngss7_event); SS7_FUNC_TRACE_EXIT(__FUNCTION__); - return; } /******************************************************************************/ @@ -455,8 +175,9 @@ void sngss7_rel_ind(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, SiRe { SS7_FUNC_TRACE_ENTER(__FUNCTION__); - sngss7_chan_data_t *sngss7_info ; - ftdm_channel_t *ftdmchan; + sngss7_chan_data_t *sngss7_info = NULL; + ftdm_channel_t *ftdmchan = NULL; + sngss7_event_data_t *sngss7_event = NULL; /* get the ftdmchan and ss7_chan_data from the circuit */ if (extract_chan_data(circuit, &sngss7_info, &ftdmchan)) { @@ -465,92 +186,36 @@ void sngss7_rel_ind(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, SiRe return; } - /* now that we have the right channel...put a lock on it so no-one else can use it */ - ftdm_mutex_lock(ftdmchan->mutex); - - /* check if there is a pending state change, give it a bit to clear */ - if (check_for_state_change(ftdmchan)) { - SS7_ERROR("Failed to wait for pending state change on CIC = %d\n", sngss7_info->circuit->cic); - ftdm_mutex_unlock(ftdmchan->mutex); + /* initalize the sngss7_event */ + sngss7_event = ftdm_malloc(sizeof(*sngss7_event)); + if (sngss7_event == NULL) { + SS7_ERROR("Failed to allocate memory for sngss7_event!\n"); SS7_FUNC_TRACE_EXIT(__FUNCTION__); - SS7_ASSERT; - }; + return; + } + memset(sngss7_event, 0x0, sizeof(*sngss7_event)); - SS7_MSG_TRACE(ftdmchan, sngss7_info, "Rx REL\n"); + /* fill in the sngss7_event struct */ + sngss7_event->spInstId = spInstId; + sngss7_event->suInstId = suInstId; + sngss7_event->circuit = circuit; + sngss7_event->event_id = SNGSS7_REL_IND_EVENT; + memcpy(&sngss7_event->event.siRelEvnt, siRelEvnt, sizeof(*siRelEvnt)); - /* check whether the ftdm channel is in a state to release a call */ - switch (ftdmchan->state) { - /**************************************************************************/ - case FTDM_CHANNEL_STATE_DIALING: - - /* pass the release code up to FTDM */ - if (siRelEvnt->causeDgn.causeVal.pres) { - ftdmchan->caller_data.hangup_cause = siRelEvnt->causeDgn.causeVal.val; - } else { - SS7_ERROR("REL does not have a cause code!\n"); - ftdmchan->caller_data.hangup_cause = 0; - } - - /* this is a remote hangup request */ - sngss7_set_flag(sngss7_info, FLAG_REMOTE_REL); - - /* move the state of the channel to CANCEL to end the call */ - ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_TERMINATING); - - break; - /**************************************************************************/ - case FTDM_CHANNEL_STATE_RING: - case FTDM_CHANNEL_STATE_PROGRESS: - case FTDM_CHANNEL_STATE_PROGRESS_MEDIA: - case FTDM_CHANNEL_STATE_UP: - - /* pass the release code up to FTDM */ - if (siRelEvnt->causeDgn.causeVal.pres) { - ftdmchan->caller_data.hangup_cause = siRelEvnt->causeDgn.causeVal.val; - } else { - SS7_ERROR("REL does not have a cause code!\n"); - ftdmchan->caller_data.hangup_cause = 0; - } - - /* this is a remote hangup request */ - sngss7_set_flag(sngss7_info, FLAG_REMOTE_REL); - - /* move the state of the channel to TERMINATING to end the call */ - ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_TERMINATING); - - break; - /**************************************************************************/ - default: - - /* fill in the channels SS7 Stack information */ - sngss7_info->suInstId = get_unique_id(); - sngss7_info->spInstId = spInstId; - - /* throw the reset flag */ - sngss7_set_flag(sngss7_info, FLAG_RESET_RX); - - /* set the state to RESTART */ - ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_RESTART); - break; - /**************************************************************************/ - } /* switch (ftdmchan->state) */ - - - /* unlock the channel */ - ftdm_mutex_unlock(ftdmchan->mutex); + /* enqueue this event */ + ftdm_queue_enqueue(((sngss7_span_data_t*)sngss7_info->ftdmchan->span->mod_data)->event_queue, sngss7_event); SS7_FUNC_TRACE_EXIT(__FUNCTION__); - return; } - /******************************************************************************/ void sngss7_rel_cfm(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, SiRelEvnt *siRelEvnt) { SS7_FUNC_TRACE_ENTER(__FUNCTION__); - - sngss7_chan_data_t *sngss7_info ; - ftdm_channel_t *ftdmchan; + + sngss7_chan_data_t *sngss7_info = NULL; + ftdm_channel_t *ftdmchan = NULL; + sngss7_event_data_t *sngss7_event = NULL; /* get the ftdmchan and ss7_chan_data from the circuit */ if (extract_chan_data(circuit, &sngss7_info, &ftdmchan)) { @@ -559,57 +224,36 @@ void sngss7_rel_cfm(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, SiRe return; } - /* now that we have the right channel...put a lock on it so no-one else can use it */ - ftdm_mutex_lock(ftdmchan->mutex); - - /* check if there is a pending state change, give it a bit to clear */ - if (check_for_state_change(ftdmchan)) { - SS7_ERROR("Failed to wait for pending state change on CIC = %d\n", sngss7_info->circuit->cic); - ftdm_mutex_unlock(ftdmchan->mutex); + /* initalize the sngss7_event */ + sngss7_event = ftdm_malloc(sizeof(*sngss7_event)); + if (sngss7_event == NULL) { + SS7_ERROR("Failed to allocate memory for sngss7_event!\n"); SS7_FUNC_TRACE_EXIT(__FUNCTION__); - SS7_ASSERT; - }; - - SS7_MSG_TRACE(ftdmchan, sngss7_info, "Rx RLC\n"); - - /* check whether the ftdm channel is in a state to accept a call */ - switch (ftdmchan->state) { - /**************************************************************************/ - case FTDM_CHANNEL_STATE_HANGUP_COMPLETE: - - /* go to DOWN */ - ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_DOWN); - - break; - /**************************************************************************/ - case FTDM_CHANNEL_STATE_DOWN: - /* do nothing, just drop the message */ - break; - /**************************************************************************/ - default: - /* KONRAD: should just stop the call...but a reset is easier for now (since it does hangup the call) */ - - /* go to RESTART */ - ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_RESTART); - - break; - /**************************************************************************/ + return; } + memset(sngss7_event, 0x0, sizeof(*sngss7_event)); - /* unlock the channel */ - ftdm_mutex_unlock(ftdmchan->mutex); + /* fill in the sngss7_event struct */ + sngss7_event->spInstId = spInstId; + sngss7_event->suInstId = suInstId; + sngss7_event->circuit = circuit; + sngss7_event->event_id = SNGSS7_REL_CFM_EVENT; + memcpy(&sngss7_event->event.siRelEvnt, siRelEvnt, sizeof(*siRelEvnt)); + + /* enqueue this event */ + ftdm_queue_enqueue(((sngss7_span_data_t*)sngss7_info->ftdmchan->span->mod_data)->event_queue, sngss7_event); SS7_FUNC_TRACE_EXIT(__FUNCTION__); - return; } /******************************************************************************/ void sngss7_dat_ind(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, SiInfoEvnt *siInfoEvnt) { SS7_FUNC_TRACE_ENTER(__FUNCTION__); - - sngss7_chan_data_t *sngss7_info ; - ftdm_channel_t *ftdmchan; + + sngss7_chan_data_t *sngss7_info = NULL; + ftdm_channel_t *ftdmchan = NULL; + sngss7_event_data_t *sngss7_event = NULL; /* get the ftdmchan and ss7_chan_data from the circuit */ if (extract_chan_data(circuit, &sngss7_info, &ftdmchan)) { @@ -618,33 +262,36 @@ void sngss7_dat_ind(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, SiIn return; } - /* now that we have the right channel...put a lock on it so no-one else can use it */ - ftdm_mutex_lock(ftdmchan->mutex); - - /* check if there is a pending state change, give it a bit to clear */ - if (check_for_state_change(ftdmchan)) { - SS7_ERROR("Failed to wait for pending state change on CIC = %d\n", sngss7_info->circuit->cic); - ftdm_mutex_unlock(ftdmchan->mutex); + /* initalize the sngss7_event */ + sngss7_event = ftdm_malloc(sizeof(*sngss7_event)); + if (sngss7_event == NULL) { + SS7_ERROR("Failed to allocate memory for sngss7_event!\n"); SS7_FUNC_TRACE_EXIT(__FUNCTION__); - SS7_ASSERT; - }; + return; + } + memset(sngss7_event, 0x0, sizeof(*sngss7_event)); - SS7_MSG_TRACE(ftdmchan, sngss7_info, "Rx DATA IND\n"); + /* fill in the sngss7_event struct */ + sngss7_event->spInstId = spInstId; + sngss7_event->suInstId = suInstId; + sngss7_event->circuit = circuit; + sngss7_event->event_id = SNGSS7_DAT_IND_EVENT; + memcpy(&sngss7_event->event.siInfoEvnt, siInfoEvnt, sizeof(*siInfoEvnt)); - /* unlock the channel */ - ftdm_mutex_unlock(ftdmchan->mutex); + /* enqueue this event */ + ftdm_queue_enqueue(((sngss7_span_data_t*)sngss7_info->ftdmchan->span->mod_data)->event_queue, sngss7_event); SS7_FUNC_TRACE_EXIT(__FUNCTION__); - return; } /******************************************************************************/ void sngss7_fac_ind(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, uint8_t evntType, SiFacEvnt *siFacEvnt) { SS7_FUNC_TRACE_ENTER(__FUNCTION__); - - sngss7_chan_data_t *sngss7_info ; - ftdm_channel_t *ftdmchan; + + sngss7_chan_data_t *sngss7_info = NULL; + ftdm_channel_t *ftdmchan = NULL; + sngss7_event_data_t *sngss7_event = NULL; /* get the ftdmchan and ss7_chan_data from the circuit */ if (extract_chan_data(circuit, &sngss7_info, &ftdmchan)) { @@ -653,33 +300,37 @@ void sngss7_fac_ind(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, uint return; } - /* now that we have the right channel...put a lock on it so no-one else can use it */ - ftdm_mutex_lock(ftdmchan->mutex); - - /* check if there is a pending state change, give it a bit to clear */ - if (check_for_state_change(ftdmchan)) { - SS7_ERROR("Failed to wait for pending state change on CIC = %d\n", sngss7_info->circuit->cic); - ftdm_mutex_unlock(ftdmchan->mutex); + /* initalize the sngss7_event */ + sngss7_event = ftdm_malloc(sizeof(*sngss7_event)); + if (sngss7_event == NULL) { + SS7_ERROR("Failed to allocate memory for sngss7_event!\n"); SS7_FUNC_TRACE_EXIT(__FUNCTION__); - SS7_ASSERT; - }; + return; + } + memset(sngss7_event, 0x0, sizeof(*sngss7_event)); - SS7_MSG_TRACE(ftdmchan, sngss7_info, "Rx FAC\n"); + /* fill in the sngss7_event struct */ + sngss7_event->spInstId = spInstId; + sngss7_event->suInstId = suInstId; + sngss7_event->circuit = circuit; + sngss7_event->evntType = evntType; + sngss7_event->event_id = SNGSS7_FAC_IND_EVENT; + memcpy(&sngss7_event->event.siFacEvnt, siFacEvnt, sizeof(*siFacEvnt)); - /* unlock the channel */ - ftdm_mutex_unlock(ftdmchan->mutex); + /* enqueue this event */ + ftdm_queue_enqueue(((sngss7_span_data_t*)sngss7_info->ftdmchan->span->mod_data)->event_queue, sngss7_event); SS7_FUNC_TRACE_EXIT(__FUNCTION__); - return; } /******************************************************************************/ void sngss7_fac_cfm(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, uint8_t evntType, SiFacEvnt *siFacEvnt) { SS7_FUNC_TRACE_ENTER(__FUNCTION__); - - sngss7_chan_data_t *sngss7_info ; - ftdm_channel_t *ftdmchan; + + sngss7_chan_data_t *sngss7_info = NULL; + ftdm_channel_t *ftdmchan = NULL; + sngss7_event_data_t *sngss7_event = NULL; /* get the ftdmchan and ss7_chan_data from the circuit */ if (extract_chan_data(circuit, &sngss7_info, &ftdmchan)) { @@ -688,33 +339,37 @@ void sngss7_fac_cfm(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, uint return; } - /* now that we have the right channel...put a lock on it so no-one else can use it */ - ftdm_mutex_lock(ftdmchan->mutex); - - /* check if there is a pending state change, give it a bit to clear */ - if (check_for_state_change(ftdmchan)) { - SS7_ERROR("Failed to wait for pending state change on CIC = %d\n", sngss7_info->circuit->cic); - ftdm_mutex_unlock(ftdmchan->mutex); + /* initalize the sngss7_event */ + sngss7_event = ftdm_malloc(sizeof(*sngss7_event)); + if (sngss7_event == NULL) { + SS7_ERROR("Failed to allocate memory for sngss7_event!\n"); SS7_FUNC_TRACE_EXIT(__FUNCTION__); - SS7_ASSERT; - }; + return; + } + memset(sngss7_event, 0x0, sizeof(*sngss7_event)); - SS7_MSG_TRACE(ftdmchan, sngss7_info, "Rx FAC-CON\n"); + /* fill in the sngss7_event struct */ + sngss7_event->spInstId = spInstId; + sngss7_event->suInstId = suInstId; + sngss7_event->circuit = circuit; + sngss7_event->evntType = evntType; + sngss7_event->event_id = SNGSS7_FAC_CFM_EVENT; + memcpy(&sngss7_event->event.siFacEvnt, siFacEvnt, sizeof(*siFacEvnt)); - /* unlock the channel */ - ftdm_mutex_unlock(ftdmchan->mutex); + /* enqueue this event */ + ftdm_queue_enqueue(((sngss7_span_data_t*)sngss7_info->ftdmchan->span->mod_data)->event_queue, sngss7_event); SS7_FUNC_TRACE_EXIT(__FUNCTION__); - return; } /******************************************************************************/ void sngss7_umsg_ind(uint32_t suInstId, uint32_t spInstId, uint32_t circuit) { SS7_FUNC_TRACE_ENTER(__FUNCTION__); - - sngss7_chan_data_t *sngss7_info ; - ftdm_channel_t *ftdmchan; + + sngss7_chan_data_t *sngss7_info = NULL; + ftdm_channel_t *ftdmchan = NULL; + sngss7_event_data_t *sngss7_event = NULL; /* get the ftdmchan and ss7_chan_data from the circuit */ if (extract_chan_data(circuit, &sngss7_info, &ftdmchan)) { @@ -723,31 +378,35 @@ void sngss7_umsg_ind(uint32_t suInstId, uint32_t spInstId, uint32_t circuit) return; } - /* now that we have the right channel...put a lock on it so no-one else can use it */ - ftdm_mutex_lock(ftdmchan->mutex); - - /* check if there is a pending state change, give it a bit to clear */ - if (check_for_state_change(ftdmchan)) { - SS7_ERROR("Failed to wait for pending state change on CIC = %d\n", sngss7_info->circuit->cic); - ftdm_mutex_unlock(ftdmchan->mutex); + /* initalize the sngss7_event */ + sngss7_event = ftdm_malloc(sizeof(*sngss7_event)); + if (sngss7_event == NULL) { + SS7_ERROR("Failed to allocate memory for sngss7_event!\n"); SS7_FUNC_TRACE_EXIT(__FUNCTION__); - SS7_ASSERT; - }; + return; + } + memset(sngss7_event, 0x0, sizeof(*sngss7_event)); - SS7_MSG_TRACE(ftdmchan, sngss7_info, "Rx USER-USER msg\n"); + /* fill in the sngss7_event struct */ + sngss7_event->spInstId = spInstId; + sngss7_event->suInstId = suInstId; + sngss7_event->circuit = circuit; + sngss7_event->event_id = SNGSS7_UMSG_IND_EVENT; - /* unlock the channel */ - ftdm_mutex_unlock(ftdmchan->mutex); + /* enqueue this event */ + ftdm_queue_enqueue(((sngss7_span_data_t*)sngss7_info->ftdmchan->span->mod_data)->event_queue, sngss7_event); SS7_FUNC_TRACE_EXIT(__FUNCTION__); - return; -} +} /* GENERAL STATUS *************************************************************/ void sngss7_sta_ind(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, uint8_t globalFlg, uint8_t evntType, SiStaEvnt *siStaEvnt) { - sngss7_chan_data_t *sngss7_info ; - ftdm_channel_t *ftdmchan; + SS7_FUNC_TRACE_ENTER(__FUNCTION__); + + sngss7_chan_data_t *sngss7_info = NULL; + ftdm_channel_t *ftdmchan = NULL; + sngss7_event_data_t *sngss7_event = NULL; /* get the ftdmchan and ss7_chan_data from the circuit */ if (extract_chan_data(circuit, &sngss7_info, &ftdmchan)) { @@ -756,1209 +415,32 @@ void sngss7_sta_ind(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, uint return; } - SS7_FUNC_TRACE_ENTER(__FUNCTION__); + /* initalize the sngss7_event */ + sngss7_event = ftdm_malloc(sizeof(*sngss7_event)); + if (sngss7_event == NULL) { + SS7_ERROR("Failed to allocate memory for sngss7_event!\n"); + SS7_FUNC_TRACE_EXIT(__FUNCTION__); + return; + } + memset(sngss7_event, 0x0, sizeof(*sngss7_event)); - switch (evntType) { - /**************************************************************************/ - case SIT_STA_REATTEMPT: /* reattempt indication */ - SS7_MSG_TRACE(ftdmchan, sngss7_info, "Rx Reattempt indication\n"); - handle_reattempt(suInstId, spInstId, circuit, globalFlg, evntType, siStaEvnt); - break; - /**************************************************************************/ - case SIT_STA_ERRORIND: /* error indication */ - SS7_MSG_TRACE(ftdmchan, sngss7_info, "Rx Error indication\n"); - SS7_WARN(" %s indication not currently supported\n", DECODE_LCC_EVENT(evntType)); - break; - /**************************************************************************/ - case SIT_STA_CONTCHK: /* continuity check */ - SS7_MSG_TRACE(ftdmchan, sngss7_info, "Rx COT start\n"); - handle_cot_start(suInstId, spInstId, circuit, globalFlg, evntType, siStaEvnt); - break; - /**************************************************************************/ - case SIT_STA_CONTREP: /* continuity report */ - SS7_MSG_TRACE(ftdmchan, sngss7_info, "Rx COT report\n"); - handle_cot(suInstId, spInstId, circuit, globalFlg, evntType, siStaEvnt); - break; - /**************************************************************************/ - case SIT_STA_STPCONTIN: /* stop continuity */ - SS7_MSG_TRACE(ftdmchan, sngss7_info, "Rx COT stop\n"); - handle_cot_stop(suInstId, spInstId, circuit, globalFlg, evntType, siStaEvnt); - break; - /**************************************************************************/ - case SIT_STA_CGQRYRSP: /* circuit grp query response from far end forwarded to upper layer by ISUP */ - SS7_MSG_TRACE(ftdmchan, sngss7_info, "Rx CQM\n"); - SS7_WARN(" %s indication not currently supported\n", DECODE_LCC_EVENT(evntType)); - break; - /**************************************************************************/ - case SIT_STA_CONFUSION: /* confusion */ - SS7_MSG_TRACE(ftdmchan, sngss7_info, "Rx CFN\n"); - SS7_WARN(" %s indication not currently supported\n", DECODE_LCC_EVENT(evntType)); - break; - /**************************************************************************/ - case SIT_STA_LOOPBACKACK: /* loop-back acknowledge */ - SS7_MSG_TRACE(ftdmchan, sngss7_info, "Rx LPA\n"); - SS7_WARN(" %s indication not currently supported\n", DECODE_LCC_EVENT(evntType)); - break; - /**************************************************************************/ - case SIT_STA_CIRRSRVREQ: /* circuit reservation request */ - SS7_MSG_TRACE(ftdmchan, sngss7_info, "Rx Ckt Resveration req\n"); - SS7_WARN(" %s indication not currently supported\n", DECODE_LCC_EVENT(evntType)); - break; - /**************************************************************************/ - case SIT_STA_CIRRSRVACK: /* circuit reservation acknowledgement */ - SS7_MSG_TRACE(ftdmchan, sngss7_info, "Rx Ckt Res ack\n"); - SS7_WARN(" %s indication not currently supported\n", DECODE_LCC_EVENT(evntType)); - break; - /**************************************************************************/ - case SIT_STA_CIRBLOREQ: /* circuit blocking request */ - SS7_MSG_TRACE(ftdmchan, sngss7_info, "Rx BLO\n"); - handle_blo_req(suInstId, spInstId, circuit, globalFlg, evntType, siStaEvnt); - break; - /**************************************************************************/ - case SIT_STA_CIRBLORSP: /* circuit blocking response */ - SS7_MSG_TRACE(ftdmchan, sngss7_info, "Rx BLA\n"); - handle_blo_rsp(suInstId, spInstId, circuit, globalFlg, evntType, siStaEvnt); - break; - /**************************************************************************/ - case SIT_STA_CIRUBLREQ: /* circuit unblocking request */ - SS7_MSG_TRACE(ftdmchan, sngss7_info, "Rx UBL\n"); - handle_ubl_req(suInstId, spInstId, circuit, globalFlg, evntType, siStaEvnt); - break; - /**************************************************************************/ - case SIT_STA_CIRUBLRSP: /* circuit unblocking response */ - SS7_MSG_TRACE(ftdmchan, sngss7_info, "Rx UBA\n"); - handle_ubl_rsp(suInstId, spInstId, circuit, globalFlg, evntType, siStaEvnt); - break; - /**************************************************************************/ - case SIT_STA_CIRRESREQ: /* circuit reset request - RSC */ - SS7_MSG_TRACE(ftdmchan, sngss7_info, "Rx RSC\n"); - handle_rsc_req(suInstId, spInstId, circuit, globalFlg, evntType, siStaEvnt); - break; - /**************************************************************************/ - case SIT_STA_CIRLOCRES: /* reset initiated locally by the software */ - SS7_MSG_TRACE(ftdmchan, sngss7_info, "Rx Local RSC\n"); - handle_local_rsc_req(suInstId, spInstId, circuit, globalFlg, evntType, siStaEvnt); - break; - /**************************************************************************/ - case SIT_STA_CIRRESRSP: /* circuit reset response */ - SS7_MSG_TRACE(ftdmchan, sngss7_info, "Rx RSC-RLC\n"); - handle_rsc_rsp(suInstId, spInstId, circuit, globalFlg, evntType, siStaEvnt); - break; - /**************************************************************************/ - case SIT_STA_CGBREQ: /* CGB request */ - SS7_MSG_TRACE(ftdmchan, sngss7_info, "Rx CGB\n"); - SS7_WARN(" %s indication not currently supported\n", DECODE_LCC_EVENT(evntType)); - break; - /**************************************************************************/ - case SIT_STA_CGUREQ: /* CGU request */ - SS7_MSG_TRACE(ftdmchan, sngss7_info, "Rx CGU\n"); - SS7_WARN(" %s indication not currently supported\n", DECODE_LCC_EVENT(evntType)); - break; - /**************************************************************************/ - case SIT_STA_CGQRYREQ: /* circuit group query request */ - SS7_MSG_TRACE(ftdmchan, sngss7_info, "Rx CQM\n"); - SS7_WARN(" %s indication not currently supported\n", DECODE_LCC_EVENT(evntType)); - break; - /**************************************************************************/ - case SIT_STA_CGBRSP: /* mntc. oriented CGB response */ - SS7_MSG_TRACE(ftdmchan, sngss7_info, "Rx mntc CGB\n"); - SS7_WARN(" %s indication not currently supported\n", DECODE_LCC_EVENT(evntType)); - break; - /**************************************************************************/ - case SIT_STA_CGURSP: /* mntc. oriented CGU response */ - SS7_MSG_TRACE(ftdmchan, sngss7_info, "Rx mntc CGU\n"); - SS7_WARN(" %s indication not currently supported\n", DECODE_LCC_EVENT(evntType)); - break; - /**************************************************************************/ - case SIT_STA_GRSREQ: /* circuit group reset request */ - SS7_MSG_TRACE(ftdmchan, sngss7_info, "Rx GRS\n"); - handle_grs_req(suInstId, spInstId, circuit, globalFlg, evntType, siStaEvnt); - break; - /**************************************************************************/ - case SIT_STA_CIRUNEQPD: /* circuit unequipped indication */ - SS7_MSG_TRACE(ftdmchan, sngss7_info, "Rx UCIC\n"); - handle_ucic(suInstId, spInstId, circuit, globalFlg, evntType, siStaEvnt); - break; - /**************************************************************************/ - case SIT_STA_GRSRSP: /* circuit group reset response */ - SS7_MSG_TRACE(ftdmchan, sngss7_info, "Rx GRA\n"); - handle_grs_rsp(suInstId, spInstId, circuit, globalFlg, evntType, siStaEvnt); - break; - /**************************************************************************/ - case SIT_STA_PAUSEIND: /* pause indication */ - SS7_MSG_TRACE(ftdmchan, sngss7_info, "Rx SUS\n"); - handle_pause(suInstId, spInstId, circuit, globalFlg, evntType, siStaEvnt); - break; - /**************************************************************************/ - case SIT_STA_RESUMEIND: /* resume indication */ - SS7_MSG_TRACE(ftdmchan, sngss7_info, "Rx RES\n"); - handle_resume(suInstId, spInstId, circuit, globalFlg, evntType, siStaEvnt); - break; - /**************************************************************************/ - case SIT_STA_USRPARTA: /* user part available */ - SS7_MSG_TRACE(ftdmchan, sngss7_info, "Rx UPA\n"); - SS7_WARN(" %s indication not currently supported\n", DECODE_LCC_EVENT(evntType)); - break; - /**************************************************************************/ - case SIT_STA_RMTUSRUNAV: /* remote user not available */ - SS7_MSG_TRACE(ftdmchan, sngss7_info, "Rx Remote User not Available\n"); - SS7_WARN(" %s indication not currently supported\n", DECODE_LCC_EVENT(evntType)); - break; - /**************************************************************************/ - case SIT_STA_MTPCONG0: /* congestion indication level 0 */ - SS7_MSG_TRACE(ftdmchan, sngss7_info, "Rx Congestion L0\n"); - SS7_WARN(" %s indication not currently supported\n", DECODE_LCC_EVENT(evntType)); - break; - /**************************************************************************/ - case SIT_STA_MTPCONG1: /* congestion indication level 1 */ - SS7_MSG_TRACE(ftdmchan, sngss7_info, "Rx Congestion L1\n"); - SS7_WARN(" %s indication not currently supported\n", DECODE_LCC_EVENT(evntType)); - break; - /**************************************************************************/ - case SIT_STA_MTPCONG2: /* congestion indication level 2 */ - SS7_MSG_TRACE(ftdmchan, sngss7_info, "Rx Congestion L2\n"); - SS7_WARN(" %s indication not currently supported\n", DECODE_LCC_EVENT(evntType)); - break; - /**************************************************************************/ - case SIT_STA_MTPCONG3: /* congestion indication level 3 */ - SS7_MSG_TRACE(ftdmchan, sngss7_info, "Rx Congestion L3\n"); - SS7_WARN(" %s indication not currently supported\n", DECODE_LCC_EVENT(evntType)); - break; - /**************************************************************************/ - case SIT_STA_MTPSTPCONG: /* stop congestion indication level 0 */ - SS7_MSG_TRACE(ftdmchan, sngss7_info, "Rx Stop Congestion\n"); - SS7_WARN(" %s indication not currently supported\n", DECODE_LCC_EVENT(evntType)); - break; - /**************************************************************************/ - case SIT_STA_CIRLOCALBLOIND: /* Mngmt local blocking */ - SS7_MSG_TRACE(ftdmchan, sngss7_info, "Rx Local BLO\n"); - handle_local_blk(suInstId, spInstId, circuit, globalFlg, evntType, siStaEvnt); - break; - /**************************************************************************/ - case SIT_STA_CIRLOCALUBLIND: /* Mngmt local unblocking */ - SS7_MSG_TRACE(ftdmchan, sngss7_info, "Rx Local UBL\n"); - handle_local_ubl(suInstId, spInstId, circuit, globalFlg, evntType, siStaEvnt); - break; - /**************************************************************************/ - case SIT_STA_OVERLOAD: /* Overload */ - SS7_MSG_TRACE(ftdmchan, sngss7_info, "Rx Overload\n"); - SS7_WARN(" %s indication not currently supported\n", DECODE_LCC_EVENT(evntType)); - break; - /**************************************************************************/ - case SIT_STA_LMCGBREQ: /* when LM requests ckt grp blocking */ - SS7_MSG_TRACE(ftdmchan, sngss7_info, "Rx LM CGB\n"); - SS7_WARN(" %s indication not currently supported\n", DECODE_LCC_EVENT(evntType)); - break; - /**************************************************************************/ - case SIT_STA_LMCGUREQ: /* when LM requests ckt grp unblocking */ - SS7_MSG_TRACE(ftdmchan, sngss7_info, "Rx LM CGU\n"); - SS7_WARN(" %s indication not currently supported\n", DECODE_LCC_EVENT(evntType)); - break; - /**************************************************************************/ - case SIT_STA_LMGRSREQ: /* when LM requests ckt grp reset */ - SS7_MSG_TRACE(ftdmchan, sngss7_info, "Rx LM RSC\n"); - SS7_WARN(" %s indication not currently supported\n", DECODE_LCC_EVENT(evntType)); - break; - /**************************************************************************/ - case SIT_STA_CGBINFOIND: /* circuit grp blking ind , no resp req */ - SS7_MSG_TRACE(ftdmchan, sngss7_info, "Rx CGB no resp req\n"); - SS7_WARN(" %s indication not currently supported\n", DECODE_LCC_EVENT(evntType)); - break; - /**************************************************************************/ - case SIT_STA_LMCQMINFOREQ: /* when LM requests ckt grp query */ - SS7_MSG_TRACE(ftdmchan, sngss7_info, "Rx LM CQM\n"); - SS7_WARN(" %s indication not currently supported\n", DECODE_LCC_EVENT(evntType)); - break; - /**************************************************************************/ - case SIT_STA_CIRLOCGRS: /* group reset initiated locally by the software */ - SS7_MSG_TRACE(ftdmchan, sngss7_info, "Rx Local GRS\n"); - SS7_WARN(" %s indication not currently supported\n", DECODE_LCC_EVENT(evntType)); - break; - /**************************************************************************/ - default: - SS7_INFO("[SNG-CC] Received Unknown indication %d\n", evntType); - break; - } /* switch (evntType) */ + /* fill in the sngss7_event struct */ + sngss7_event->spInstId = spInstId; + sngss7_event->suInstId = suInstId; + sngss7_event->circuit = circuit; + sngss7_event->globalFlg = globalFlg; + sngss7_event->evntType = evntType; + sngss7_event->event_id = SNGSS7_STA_IND_EVENT; + if (siStaEvnt != NULL) { + memcpy(&sngss7_event->event.siStaEvnt, siStaEvnt, sizeof(*siStaEvnt)); + } + + /* enqueue this event */ + ftdm_queue_enqueue(((sngss7_span_data_t*)sngss7_info->ftdmchan->span->mod_data)->event_queue, sngss7_event); SS7_FUNC_TRACE_EXIT(__FUNCTION__); - return; } -/******************************************************************************/ -static ftdm_status_t handle_reattempt(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, uint8_t globalFlg, uint8_t evntType, SiStaEvnt *siStaEvnt) -{ - SS7_FUNC_TRACE_ENTER(__FUNCTION__); - - sngss7_chan_data_t *sngss7_info = NULL; - ftdm_channel_t *ftdmchan = NULL; - - /* get the ftdmchan and ss7_chan_data from the circuit */ - if (extract_chan_data(circuit, &sngss7_info, &ftdmchan)) { - SS7_ERROR("Failed to extract channel data for ISUP circuit = %d!\n", circuit); - SS7_FUNC_TRACE_EXIT(__FUNCTION__); - return FTDM_FAIL; - } - - /* now that we have the right channel...put a lock on it so no-one else can use it */ - ftdm_mutex_lock(ftdmchan->mutex); - - /* check if there is a pending state change, give it a bit to clear */ - if (check_for_state_change(ftdmchan)) { - SS7_ERROR("Failed to wait for pending state change on CIC = %d\n", sngss7_info->circuit->cic); - ftdm_mutex_unlock(ftdmchan->mutex); - SS7_FUNC_TRACE_EXIT(__FUNCTION__); - SS7_ASSERT; - }; - - /* glare, throw the flag, go to down state*/ - sngss7_set_flag(sngss7_info, FLAG_GLARE); - - ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_CANCEL); - - /* unlock the channel again before we exit */ - ftdm_mutex_unlock(ftdmchan->mutex); - - SS7_FUNC_TRACE_EXIT(__FUNCTION__); - return FTDM_SUCCESS; -} - -/******************************************************************************/ -static ftdm_status_t handle_pause(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, uint8_t globalFlg, uint8_t evntType, SiStaEvnt *siStaEvnt) -{ - SS7_FUNC_TRACE_ENTER(__FUNCTION__); - - sngss7_chan_data_t *sngss7_info = NULL; - ftdm_channel_t *ftdmchan = NULL; - int infId; - int i; - - /* extract the affect infId from the circuit structure */ - infId = g_ftdm_sngss7_data.cfg.isupCkt[circuit].infId; - - /* go through all the circuits now and find any other circuits on this infId */ - i = 1; - while (g_ftdm_sngss7_data.cfg.isupCkt[i].id != 0) { - - /* check that the infId matches and that this is not a siglink */ - if ((g_ftdm_sngss7_data.cfg.isupCkt[i].infId == infId) && - (g_ftdm_sngss7_data.cfg.isupCkt[i].type == VOICE)) { - - /* get the ftdmchan and ss7_chan_data from the circuit */ - if (extract_chan_data(i, &sngss7_info, &ftdmchan)) { - SS7_ERROR("Failed to extract channel data for circuit = %d!\n", circuit); - i++; - continue; - } - - /* lock the channel */ - ftdm_mutex_lock(ftdmchan->mutex); - - /* check if there is a pending state change, give it a bit to clear */ - if (check_for_state_change(ftdmchan)) { - SS7_ERROR("Failed to wait for pending state change on CIC = %d\n", sngss7_info->circuit->cic); - ftdm_mutex_unlock(ftdmchan->mutex); - i++; - SS7_ASSERT; - }; - - /* check if the circuit is fully started */ - if (ftdm_test_flag(ftdmchan->span, FTDM_SPAN_IN_THREAD)) { - /* set the pause flag on the channel */ - sngss7_set_flag(sngss7_info, FLAG_INFID_PAUSED); - - /* set the statet o SUSPENDED to bring the sig status down */ - ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_SUSPENDED); - } - - /* unlock the channel again before we exit */ - ftdm_mutex_unlock(ftdmchan->mutex); - - } /* if (g_ftdm_sngss7_data.cfg.isupCkt[i].infId == infId) */ - - /* move to the next circuit */ - i++; - - } /* while (g_ftdm_sngss7_data.cfg.isupCkt[i].id != 0) */ - - SS7_FUNC_TRACE_EXIT(__FUNCTION__); - return FTDM_SUCCESS; -} - -/******************************************************************************/ -static ftdm_status_t handle_resume(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, uint8_t globalFlg, uint8_t evntType, SiStaEvnt *siStaEvnt) -{ - SS7_FUNC_TRACE_ENTER(__FUNCTION__); - - sngss7_chan_data_t *sngss7_info = NULL; - ftdm_channel_t *ftdmchan = NULL; - int infId; - int i; - - /* extract the affect infId from the circuit structure */ - infId = g_ftdm_sngss7_data.cfg.isupCkt[circuit].infId; - - /* go through all the circuits now and find any other circuits on this infId */ - i = 1; - while (g_ftdm_sngss7_data.cfg.isupCkt[i].id != 0) { - - /* check that the infId matches and that this is not a siglink */ - if ((g_ftdm_sngss7_data.cfg.isupCkt[i].infId == infId) && - (g_ftdm_sngss7_data.cfg.isupCkt[i].type == VOICE)) { - - /* get the ftdmchan and ss7_chan_data from the circuit */ - if (extract_chan_data(i, &sngss7_info, &ftdmchan)) { - SS7_ERROR("Failed to extract channel data for circuit = %d!\n", circuit); - i++; - continue; - } - - /* lock the channel */ - ftdm_mutex_lock(ftdmchan->mutex); - - /* check if there is a pending state change, give it a bit to clear */ - if (check_for_state_change(ftdmchan)) { - SS7_ERROR("Failed to wait for pending state change on CIC = %d\n", sngss7_info->circuit->cic); - ftdm_mutex_unlock(ftdmchan->mutex); - i++; - SS7_ASSERT; - }; - - /* only resume if we are paused */ - if (sngss7_test_flag(sngss7_info, FLAG_INFID_PAUSED)) { - /* set the resume flag on the channel */ - sngss7_set_flag(sngss7_info, FLAG_INFID_RESUME); - - /* clear the paused flag */ - sngss7_clear_flag(sngss7_info, FLAG_INFID_PAUSED); - - /* set the statet to SUSPENDED to bring the sig status up */ - ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_SUSPENDED); - } - - /* unlock the channel again before we exit */ - ftdm_mutex_unlock(ftdmchan->mutex); - - } /* if (g_ftdm_sngss7_data.cfg.isupCkt[i].infId == infId) */ - - /* move to the next circuit */ - i++; - - } /* while (g_ftdm_sngss7_data.cfg.isupCkt[i].id != 0) */ - - SS7_FUNC_TRACE_EXIT(__FUNCTION__); - return FTDM_SUCCESS; -} - -/******************************************************************************/ -static ftdm_status_t handle_cot_start(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, uint8_t globalFlg, uint8_t evntType, SiStaEvnt *siStaEvnt) -{ - SS7_FUNC_TRACE_ENTER(__FUNCTION__); - - sngss7_chan_data_t *sngss7_info = NULL; - ftdm_channel_t *ftdmchan = NULL; - - /* get the ftdmchan and ss7_chan_data from the circuit */ - if (extract_chan_data(circuit, &sngss7_info, &ftdmchan)) { - SS7_ERROR("Failed to extract channel data for circuit = %d!\n", circuit); - SS7_FUNC_TRACE_EXIT(__FUNCTION__); - return FTDM_FAIL; - } - - /* now that we have the right channel...put a lock on it so no-one else can use it */ - ftdm_mutex_lock(ftdmchan->mutex); - - /* check if there is a pending state change, give it a bit to clear */ - if (check_for_state_change(ftdmchan)) { - SS7_ERROR("Failed to wait for pending state change on CIC = %d\n", sngss7_info->circuit->cic); - ftdm_mutex_unlock(ftdmchan->mutex); - SS7_FUNC_TRACE_EXIT(__FUNCTION__); - SS7_ASSERT; - }; - - /* open the channel if it is not open */ - if (!ftdm_test_flag(ftdmchan, FTDM_CHANNEL_OPEN)) { - if (ftdm_channel_open_chan(ftdmchan) != FTDM_SUCCESS) { - SS7_ERROR("Failed to open CIC %d for COT test!\n", sngss7_info->circuit->cic); - /* KONRAD FIX ME */ - SS7_FUNC_TRACE_EXIT(__FUNCTION__); - return FTDM_FAIL; - } - } - - /* tell the core to loop the channel */ - ftdm_channel_command(ftdmchan, FTDM_COMMAND_ENABLE_LOOP, NULL); - - /* switch to the IN_LOOP state */ - ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_IN_LOOP); - - /* store the sngss7 ids */ - if (suInstId == 0) { - sngss7_info->suInstId = get_unique_id(); - } else { - sngss7_info->suInstId = suInstId; - } - sngss7_info->spInstId = spInstId; - sngss7_info->globalFlg = globalFlg; - - /* unlock the channel again before we exit */ - ftdm_mutex_unlock(ftdmchan->mutex); - - SS7_FUNC_TRACE_EXIT(__FUNCTION__); - return FTDM_SUCCESS; -} - -/******************************************************************************/ -static ftdm_status_t handle_cot_stop(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, uint8_t globalFlg, uint8_t evntType, SiStaEvnt *siStaEvnt) -{ - SS7_FUNC_TRACE_ENTER(__FUNCTION__); - - sngss7_chan_data_t *sngss7_info = NULL; - ftdm_channel_t *ftdmchan = NULL; - - /* get the ftdmchan and ss7_chan_data from the circuit */ - if (extract_chan_data(circuit, &sngss7_info, &ftdmchan)) { - SS7_ERROR("Failed to extract channel data for circuit = %d!\n", circuit); - SS7_FUNC_TRACE_EXIT(__FUNCTION__); - return FTDM_FAIL; - } - - /* now that we have the right channel...put a lock on it so no-one else can use it */ - ftdm_mutex_lock(ftdmchan->mutex); - - /* check if there is a pending state change, give it a bit to clear */ - if (check_for_state_change(ftdmchan)) { - SS7_ERROR("Failed to wait for pending state change on CIC = %d\n", sngss7_info->circuit->cic); - ftdm_mutex_unlock(ftdmchan->mutex); - SS7_FUNC_TRACE_EXIT(__FUNCTION__); - SS7_ASSERT; - }; - - /* tell the core to stop looping the channel */ - ftdm_channel_command(ftdmchan, FTDM_COMMAND_DISABLE_LOOP, NULL); - - /* exit out of the LOOP state to the last state */ - ftdm_set_state_locked(ftdmchan, ftdmchan->last_state); - - /* unlock the channel again before we exit */ - ftdm_mutex_unlock(ftdmchan->mutex); - - SS7_FUNC_TRACE_EXIT(__FUNCTION__); - return FTDM_SUCCESS; -} - -/******************************************************************************/ -static ftdm_status_t handle_cot(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, uint8_t globalFlg, uint8_t evntType, SiStaEvnt *siStaEvnt) -{ - SS7_FUNC_TRACE_ENTER(__FUNCTION__); - - if ( (siStaEvnt->contInd.eh.pres > 0) && (siStaEvnt->contInd.contInd.pres > 0)) { - SS7_INFO("Continuity Test result for CIC = %d (span %d, chan %d) is: \"%s\"\n", - g_ftdm_sngss7_data.cfg.isupCkt[circuit].cic, - g_ftdm_sngss7_data.cfg.isupCkt[circuit].span, - g_ftdm_sngss7_data.cfg.isupCkt[circuit].chan, - (siStaEvnt->contInd.contInd.val) ? "PASS" : "FAIL"); - } else { - SS7_ERROR("Recieved Continuity report containing no results!\n"); - } - - SS7_FUNC_TRACE_EXIT(__FUNCTION__); - return FTDM_SUCCESS; -} - -/******************************************************************************/ - - -/******************************************************************************/ -static ftdm_status_t handle_blo_req(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, uint8_t globalFlg, uint8_t evntType, SiStaEvnt *siStaEvnt) -{ - SS7_FUNC_TRACE_ENTER(__FUNCTION__); - - sngss7_chan_data_t *sngss7_info = NULL; - ftdm_channel_t *ftdmchan = NULL; - - /* get the ftdmchan and ss7_chan_data from the circuit */ - if (extract_chan_data(circuit, &sngss7_info, &ftdmchan)) { - SS7_ERROR("Failed to extract channel data for circuit = %d!\n", circuit); - SS7_FUNC_TRACE_EXIT(__FUNCTION__); - return FTDM_FAIL; - } - - /* now that we have the right channel...put a lock on it so no-one else can use it */ - ftdm_mutex_lock(ftdmchan->mutex); - - /* check if there is a pending state change, give it a bit to clear */ - if (check_for_state_change(ftdmchan)) { - SS7_ERROR("Failed to wait for pending state change on CIC = %d\n", sngss7_info->circuit->cic); - ftdm_mutex_unlock(ftdmchan->mutex); - SS7_FUNC_TRACE_EXIT(__FUNCTION__); - SS7_ASSERT; - }; - - /* check if the circuit is already blocked or not */ - if (sngss7_test_flag(sngss7_info, FLAG_CKT_MN_BLOCK_RX)) { - SS7_WARN("Received BLO on circuit that is already blocked!\n"); - } - - /* throw the ckt block flag */ - sngss7_set_flag(sngss7_info, FLAG_CKT_MN_BLOCK_RX); - - /* set the channel to suspended state */ - ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_SUSPENDED); - - /* unlock the channel again before we exit */ - ftdm_mutex_unlock(ftdmchan->mutex); - - SS7_FUNC_TRACE_EXIT(__FUNCTION__); - return FTDM_SUCCESS; -} - -/******************************************************************************/ -static ftdm_status_t handle_blo_rsp(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, uint8_t globalFlg, uint8_t evntType, SiStaEvnt *siStaEvnt) -{ - SS7_FUNC_TRACE_ENTER(__FUNCTION__); - - sngss7_chan_data_t *sngss7_info = NULL; - ftdm_channel_t *ftdmchan = NULL; - - /* get the ftdmchan and ss7_chan_data from the circuit */ - if (extract_chan_data(circuit, &sngss7_info, &ftdmchan)) { - SS7_ERROR("Failed to extract channel data for circuit = %d!\n", circuit); - SS7_FUNC_TRACE_EXIT(__FUNCTION__); - return FTDM_FAIL; - } - - /* now that we have the right channel...put a lock on it so no-one else can use it */ - ftdm_mutex_lock(ftdmchan->mutex); - - /* check if there is a pending state change, give it a bit to clear */ - if (check_for_state_change(ftdmchan)) { - SS7_ERROR("Failed to wait for pending state change on CIC = %d\n", sngss7_info->circuit->cic); - ftdm_mutex_unlock(ftdmchan->mutex); - SS7_FUNC_TRACE_EXIT(__FUNCTION__); - SS7_ASSERT; - }; - - /* KONRAD FIX ME */ - - /* unlock the channel again before we exit */ - ftdm_mutex_unlock(ftdmchan->mutex); - - SS7_FUNC_TRACE_EXIT(__FUNCTION__); - return FTDM_SUCCESS; -} - -/******************************************************************************/ -static ftdm_status_t handle_ubl_req(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, uint8_t globalFlg, uint8_t evntType, SiStaEvnt *siStaEvnt) -{ - SS7_FUNC_TRACE_ENTER(__FUNCTION__); - - sngss7_chan_data_t *sngss7_info = NULL; - ftdm_channel_t *ftdmchan = NULL; - - /* get the ftdmchan and ss7_chan_data from the circuit */ - if (extract_chan_data(circuit, &sngss7_info, &ftdmchan)) { - SS7_ERROR("Failed to extract channel data for circuit = %d!\n", circuit); - SS7_FUNC_TRACE_EXIT(__FUNCTION__); - return FTDM_FAIL; - } - - /* now that we have the right channel...put a lock on it so no-one else can use it */ - ftdm_mutex_lock(ftdmchan->mutex); - - /* check if there is a pending state change, give it a bit to clear */ - if (check_for_state_change(ftdmchan)) { - SS7_ERROR("Failed to wait for pending state change on CIC = %d\n", sngss7_info->circuit->cic); - ftdm_mutex_unlock(ftdmchan->mutex); - SS7_FUNC_TRACE_EXIT(__FUNCTION__); - SS7_ASSERT; - }; - - /* check if the channel is blocked */ - if (!(sngss7_test_flag(sngss7_info, FLAG_CKT_MN_BLOCK_RX))) { - SS7_WARN("Received UBL on circuit that is not blocked!\n"); - } - - /* throw the unblock flag */ - sngss7_set_flag(sngss7_info, FLAG_CKT_MN_UNBLK_RX); - - /* clear the block flag */ - sngss7_clear_flag(sngss7_info, FLAG_CKT_MN_BLOCK_RX); - - /* set the channel to suspended state */ - ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_SUSPENDED); - - /* unlock the channel again before we exit */ - ftdm_mutex_unlock(ftdmchan->mutex); - - SS7_FUNC_TRACE_EXIT(__FUNCTION__); - return FTDM_SUCCESS; -} - -/******************************************************************************/ -static ftdm_status_t handle_ubl_rsp(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, uint8_t globalFlg, uint8_t evntType, SiStaEvnt *siStaEvnt) -{ - SS7_FUNC_TRACE_ENTER(__FUNCTION__); - - sngss7_chan_data_t *sngss7_info = NULL; - ftdm_channel_t *ftdmchan = NULL; - - /* get the ftdmchan and ss7_chan_data from the circuit */ - if (extract_chan_data(circuit, &sngss7_info, &ftdmchan)) { - SS7_ERROR("Failed to extract channel data for circuit = %d!\n", circuit); - SS7_FUNC_TRACE_EXIT(__FUNCTION__); - return FTDM_FAIL; - } - - /* now that we have the right channel...put a lock on it so no-one else can use it */ - ftdm_mutex_lock(ftdmchan->mutex); - - /* check if there is a pending state change, give it a bit to clear */ - if (check_for_state_change(ftdmchan)) { - SS7_ERROR("Failed to wait for pending state change on CIC = %d\n", sngss7_info->circuit->cic); - ftdm_mutex_unlock(ftdmchan->mutex); - SS7_FUNC_TRACE_EXIT(__FUNCTION__); - SS7_ASSERT; - }; - - /* KONRAD FIX ME */ - - /* unlock the channel again before we exit */ - ftdm_mutex_unlock(ftdmchan->mutex); - - SS7_FUNC_TRACE_EXIT(__FUNCTION__); - return FTDM_SUCCESS; -} - -/******************************************************************************/ -static ftdm_status_t handle_rsc_req(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, uint8_t globalFlg, uint8_t evntType, SiStaEvnt *siStaEvnt) -{ - SS7_FUNC_TRACE_ENTER(__FUNCTION__); - - sngss7_chan_data_t *sngss7_info = NULL; - ftdm_channel_t *ftdmchan = NULL; - - /* get the ftdmchan and ss7_chan_data from the circuit */ - if (extract_chan_data(circuit, &sngss7_info, &ftdmchan)) { - SS7_ERROR("Failed to extract channel data for circuit = %d!\n", circuit); - SS7_FUNC_TRACE_EXIT(__FUNCTION__); - return FTDM_FAIL; - } - - /* now that we have the right channel...put a lock on it so no-one else can use it */ - ftdm_mutex_lock(ftdmchan->mutex); - - /* check if there is a pending state change, give it a bit to clear */ - if (check_for_state_change(ftdmchan)) { - SS7_ERROR("Failed to wait for pending state change on CIC = %d\n", sngss7_info->circuit->cic); - ftdm_mutex_unlock(ftdmchan->mutex); - SS7_FUNC_TRACE_EXIT(__FUNCTION__); - SS7_ASSERT; - }; - - /* throw the reset flag */ - sngss7_set_flag(sngss7_info, FLAG_RESET_RX); - - switch (ftdmchan->state) { - /**************************************************************************/ - case FTDM_CHANNEL_STATE_RESTART: - - /* go to idle so that we can redo the restart state*/ - ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_IDLE); - - break; - /**************************************************************************/ - default: - - /* set the state of the channel to restart...the rest is done by the chan monitor */ - ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_RESTART); - break; - /**************************************************************************/ - } - - /* unlock the channel again before we exit */ - ftdm_mutex_unlock(ftdmchan->mutex); - - SS7_FUNC_TRACE_EXIT(__FUNCTION__); - return FTDM_SUCCESS; -} - -/******************************************************************************/ -static ftdm_status_t handle_local_rsc_req(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, uint8_t globalFlg, uint8_t evntType, SiStaEvnt *siStaEvnt) -{ - SS7_FUNC_TRACE_ENTER(__FUNCTION__); - - sngss7_chan_data_t *sngss7_info = NULL; - ftdm_channel_t *ftdmchan = NULL; - - /* get the ftdmchan and ss7_chan_data from the circuit */ - if (extract_chan_data(circuit, &sngss7_info, &ftdmchan)) { - SS7_ERROR("Failed to extract channel data for circuit = %d!\n", circuit); - SS7_FUNC_TRACE_EXIT(__FUNCTION__); - return FTDM_FAIL; - } - - /* now that we have the right channel...put a lock on it so no-one else can use it */ - ftdm_mutex_lock(ftdmchan->mutex); - - /* check if there is a pending state change, give it a bit to clear */ - if (check_for_state_change(ftdmchan)) { - SS7_ERROR("Failed to wait for pending state change on CIC = %d\n", sngss7_info->circuit->cic); - ftdm_mutex_unlock(ftdmchan->mutex); - SS7_FUNC_TRACE_EXIT(__FUNCTION__); - SS7_ASSERT; - }; - - /* throw the reset flag */ - sngss7_set_flag(sngss7_info, FLAG_RESET_RX); - - switch (ftdmchan->state) { - /**************************************************************************/ - case FTDM_CHANNEL_STATE_RESTART: - - /* go to idle so that we can redo the restart state*/ - ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_IDLE); - - break; - /**************************************************************************/ - default: - - /* set the state of the channel to restart...the rest is done by the chan monitor */ - ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_RESTART); - break; - /**************************************************************************/ - } - - /* unlock the channel again before we exit */ - ftdm_mutex_unlock(ftdmchan->mutex); - - SS7_FUNC_TRACE_EXIT(__FUNCTION__); - return FTDM_SUCCESS; -} - -/******************************************************************************/ -static ftdm_status_t handle_rsc_rsp(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, uint8_t globalFlg, uint8_t evntType, SiStaEvnt *siStaEvnt) -{ - SS7_FUNC_TRACE_ENTER(__FUNCTION__); - - sngss7_chan_data_t *sngss7_info = NULL; - ftdm_channel_t *ftdmchan = NULL; - - /* get the ftdmchan and ss7_chan_data from the circuit */ - if (extract_chan_data(circuit, &sngss7_info, &ftdmchan)) { - SS7_ERROR("Failed to extract channel data for circuit = %d!\n", circuit); - SS7_FUNC_TRACE_EXIT(__FUNCTION__); - return FTDM_FAIL; - } - - /* now that we have the right channel...put a lock on it so no-one else can use it */ - ftdm_mutex_lock(ftdmchan->mutex); - - /* check if there is a pending state change, give it a bit to clear */ - if (check_for_state_change(ftdmchan)) { - SS7_ERROR("Failed to wait for pending state change on CIC = %d\n", sngss7_info->circuit->cic); - ftdm_mutex_unlock(ftdmchan->mutex); - SS7_FUNC_TRACE_EXIT(__FUNCTION__); - SS7_ASSERT; - }; - - switch (ftdmchan->state) { - /**********************************************************************/ - case FTDM_CHANNEL_STATE_RESTART: - - if ( sngss7_test_flag(sngss7_info, FLAG_RESET_TX) ) { - /* throw the FLAG_RESET_TX_RSP to indicate we have acknowledgement from the remote side */ - sngss7_set_flag(sngss7_info, FLAG_RESET_TX_RSP); - - /* go to DOWN */ - ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_DOWN); - } else { - SS7_ERROR("Received RSC-RLC but we're not waiting on a RSC-RLC on CIC #, dropping\n", sngss7_info->circuit->cic); - } - - break; - /**********************************************************************/ - case FTDM_CHANNEL_STATE_DOWN: - - /* do nothing, just drop the message */ - SS7_DEBUG("Receveived RSC-RLC in down state, dropping\n"); - - break; - /**********************************************************************/ - case FTDM_CHANNEL_STATE_TERMINATING: - case FTDM_CHANNEL_STATE_HANGUP: - case FTDM_CHANNEL_STATE_HANGUP_COMPLETE: - - /* throw the FLAG_RESET_TX_RSP to indicate we have acknowledgement from the remote side */ - sngss7_set_flag(sngss7_info, FLAG_RESET_TX_RSP); - - /* go to DOWN */ - ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_DOWN); - - break; - /**********************************************************************/ - default: - /* ITU Q764-2.9.5.1.c -> release the circuit */ - if ((siStaEvnt != NULL) && - (siStaEvnt->causeDgn.eh.pres ==PRSNT_NODEF) && - (siStaEvnt->causeDgn.causeVal.pres == PRSNT_NODEF)) { - ftdmchan->caller_data.hangup_cause = siStaEvnt->causeDgn.causeVal.val; - } else { - ftdmchan->caller_data.hangup_cause = 98; /* Message not compatiable with call state */ - } - - ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_TERMINATING); - break; - /**********************************************************************/ - } - - /* unlock the channel again before we exit */ - ftdm_mutex_unlock(ftdmchan->mutex); - - SS7_FUNC_TRACE_EXIT(__FUNCTION__); - return FTDM_SUCCESS; -} -/******************************************************************************/ -static ftdm_status_t handle_grs_req(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, uint8_t globalFlg, uint8_t evntType, SiStaEvnt *siStaEvnt) -{ - SS7_FUNC_TRACE_ENTER(__FUNCTION__); - - sngss7_chan_data_t *sngss7_info = NULL; - ftdm_channel_t *ftdmchan = NULL; - sngss7_span_data_t *span = NULL; - int range; - int x; - - if (extract_chan_data(circuit, &sngss7_info, &ftdmchan)) { - SS7_ERROR("Failed to extract channel data for circuit = %d!\n", circuit); - SS7_FUNC_TRACE_EXIT(__FUNCTION__); - return FTDM_FAIL; - } - - /* extract the range value from the event structure */ - if ((siStaEvnt->rangStat.eh.pres == PRSNT_NODEF) && (siStaEvnt->rangStat.range.pres == PRSNT_NODEF)) { - range = siStaEvnt->rangStat.range.val; - } else { - SS7_ERROR("Received GRS with no range value on CIC = %d\n", sngss7_info->circuit->cic); - SS7_FUNC_TRACE_EXIT(__FUNCTION__); - return FTDM_FAIL; - } - - /* loop over the cics starting from circuit until range+1 */ - for (x = circuit; x < (circuit + range + 1); x++) { - /* grab the circuit in question */ - if (extract_chan_data(x, &sngss7_info, &ftdmchan)) { - SS7_ERROR("Failed to extract channel data for circuit = %d!\n", x); - break; - } - - /* now that we have the right channel...put a lock on it so no-one else can use it */ - ftdm_mutex_lock(ftdmchan->mutex); - - /* check if there is a pending state change, give it a bit to clear */ - if (check_for_state_change(ftdmchan)) { - SS7_ERROR("Failed to wait for pending state change on CIC = %d\n", sngss7_info->circuit->cic); - ftdm_mutex_unlock(ftdmchan->mutex); - SS7_ASSERT; - }; - - /* fill in the span structure for this circuit */ - span = ftdmchan->span->mod_data; - span->grs.circuit = circuit; - span->grs.range = range; - - SS7_DEBUG_CHAN(ftdmchan, "Rx GRS (%d:%d)\n", - g_ftdm_sngss7_data.cfg.isupCkt[circuit].cic, - (g_ftdm_sngss7_data.cfg.isupCkt[circuit].cic + range)); - - /* flag the channel as having received a reset */ - sngss7_set_flag(sngss7_info, FLAG_GRP_RESET_RX); - - switch (ftdmchan->state) { - /**************************************************************************/ - case FTDM_CHANNEL_STATE_RESTART: - - /* go to idle so that we can redo the restart state*/ - ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_IDLE); - - break; - /**************************************************************************/ - default: - - /* set the state of the channel to restart...the rest is done by the chan monitor */ - ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_RESTART); - break; - /**************************************************************************/ - } - - /* unlock the channel again before we exit */ - ftdm_mutex_unlock(ftdmchan->mutex); - - } - - SS7_FUNC_TRACE_EXIT(__FUNCTION__); - return FTDM_SUCCESS; -} - -/******************************************************************************/ -static ftdm_status_t handle_grs_rsp(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, uint8_t globalFlg, uint8_t evntType, SiStaEvnt *siStaEvnt) -{ - SS7_FUNC_TRACE_ENTER(__FUNCTION__); - - sngss7_chan_data_t *sngss7_info = NULL; - ftdm_channel_t *ftdmchan = NULL; - int range; - int x; - - /* extract the range value from the event structure */ - if ((siStaEvnt->rangStat.eh.pres == PRSNT_NODEF) && (siStaEvnt->rangStat.range.pres == PRSNT_NODEF)) { - range = siStaEvnt->rangStat.range.val; - } else { - SS7_ERROR("Received GRA with no range value on CIC = %d\n", sngss7_info->circuit->cic); - SS7_FUNC_TRACE_EXIT(__FUNCTION__); - return FTDM_FAIL; - } - - /* go through all the circuits in the range */ - for ( x = circuit; x < (circuit + range + 1); x++) { - - /* grab the circuit in question */ - if (extract_chan_data(x, &sngss7_info, &ftdmchan)) { - SS7_ERROR("Failed to extract channel data for circuit = %d!\n", circuit); - break; - } - - /* now that we have the right channel...put a lock on it so no-one else can use it */ - ftdm_mutex_lock(ftdmchan->mutex); - - /* check if there is a pending state change, give it a bit to clear */ - if (check_for_state_change(ftdmchan)) { - SS7_ERROR("Failed to wait for pending state change on CIC = %d\n", sngss7_info->circuit->cic); - ftdm_mutex_unlock(ftdmchan->mutex); - SS7_ASSERT; - }; - - SS7_DEBUG_CHAN(ftdmchan, "Rx GRA (%d:%d)\n", - g_ftdm_sngss7_data.cfg.isupCkt[circuit].cic, - (g_ftdm_sngss7_data.cfg.isupCkt[circuit].cic + range)); - - switch (ftdmchan->state) { - /**********************************************************************/ - case FTDM_CHANNEL_STATE_RESTART: - - /* throw the FLAG_RESET_TX_RSP to indicate we have acknowledgement from the remote side */ - sngss7_set_flag(sngss7_info, FLAG_GRP_RESET_TX_RSP); - - /* go to DOWN */ - ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_DOWN); - - break; - /**********************************************************************/ - case FTDM_CHANNEL_STATE_DOWN: - - /* do nothing, just drop the message */ - SS7_DEBUG("Receveived GRA in down state, dropping\n"); - - break; - /**********************************************************************/ - case FTDM_CHANNEL_STATE_TERMINATING: - case FTDM_CHANNEL_STATE_HANGUP: - case FTDM_CHANNEL_STATE_HANGUP_COMPLETE: - - /* throw the FLAG_RESET_TX_RSP to indicate we have acknowledgement from the remote side */ - sngss7_set_flag(sngss7_info, FLAG_GRP_RESET_TX_RSP); - - break; - /**********************************************************************/ - default: - /* ITU Q764-2.9.5.1.c -> release the circuit */ - if ((siStaEvnt != NULL) && - (siStaEvnt->causeDgn.eh.pres ==PRSNT_NODEF) && - (siStaEvnt->causeDgn.causeVal.pres == PRSNT_NODEF)) { - ftdmchan->caller_data.hangup_cause = siStaEvnt->causeDgn.causeVal.val; - } else { - ftdmchan->caller_data.hangup_cause = 98; /* Message not compatiable with call state */ - } - - /* go to terminating to hang up the call */ - ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_TERMINATING); - break; - /**********************************************************************/ - } - - /* unlock the channel again before we exit */ - ftdm_mutex_unlock(ftdmchan->mutex); - - } /* for (( x = 0; x < (circuit + range); x++) */ - - SS7_FUNC_TRACE_EXIT(__FUNCTION__); - return FTDM_SUCCESS; -} - -/******************************************************************************/ -static ftdm_status_t handle_local_blk(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, uint8_t globalFlg, uint8_t evntType, SiStaEvnt *siStaEvnt) -{ - SS7_FUNC_TRACE_ENTER(__FUNCTION__); - - sngss7_chan_data_t *sngss7_info = NULL; - ftdm_channel_t *ftdmchan = NULL; - - /* get the ftdmchan and ss7_chan_data from the circuit */ - if (extract_chan_data(circuit, &sngss7_info, &ftdmchan)) { - SS7_ERROR("Failed to extract channel data for circuit = %d!\n", circuit); - SS7_FUNC_TRACE_EXIT(__FUNCTION__); - return FTDM_FAIL; - } - - /* now that we have the right channel...put a lock on it so no-one else can use it */ - ftdm_mutex_lock(ftdmchan->mutex); - - /* check if there is a pending state change, give it a bit to clear */ - if (check_for_state_change(ftdmchan)) { - SS7_ERROR("Failed to wait for pending state change on CIC = %d\n", sngss7_info->circuit->cic); - ftdm_mutex_unlock(ftdmchan->mutex); - SS7_FUNC_TRACE_EXIT(__FUNCTION__); - SS7_ASSERT; - }; - - /* check if the circuit is already blocked or not */ - if (sngss7_test_flag(sngss7_info, FLAG_CKT_LC_BLOCK_RX)) { - SS7_WARN("Received local BLO on circuit that is already blocked!\n"); - } - - /* throw the ckt block flag */ - sngss7_set_flag(sngss7_info, FLAG_CKT_LC_BLOCK_RX); - - /* set the channel to suspended state */ - ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_SUSPENDED); - - /* unlock the channel again before we exit */ - ftdm_mutex_unlock(ftdmchan->mutex); - - SS7_FUNC_TRACE_EXIT(__FUNCTION__); - return FTDM_SUCCESS; -} - -/******************************************************************************/ -static ftdm_status_t handle_local_ubl(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, uint8_t globalFlg, uint8_t evntType, SiStaEvnt *siStaEvnt) -{ - SS7_FUNC_TRACE_ENTER(__FUNCTION__); - - sngss7_chan_data_t *sngss7_info = NULL; - ftdm_channel_t *ftdmchan = NULL; - - /* get the ftdmchan and ss7_chan_data from the circuit */ - if (extract_chan_data(circuit, &sngss7_info, &ftdmchan)) { - SS7_ERROR("Failed to extract channel data for circuit = %d!\n", circuit); - SS7_FUNC_TRACE_EXIT(__FUNCTION__); - return FTDM_FAIL; - } - - /* now that we have the right channel...put a lock on it so no-one else can use it */ - ftdm_mutex_lock(ftdmchan->mutex); - - /* check if there is a pending state change, give it a bit to clear */ - if (check_for_state_change(ftdmchan)) { - SS7_ERROR("Failed to wait for pending state change on CIC = %d\n", sngss7_info->circuit->cic); - ftdm_mutex_unlock(ftdmchan->mutex); - SS7_FUNC_TRACE_EXIT(__FUNCTION__); - SS7_ASSERT; - }; - - /* check if the circuit is already blocked or not */ - if (sngss7_test_flag(sngss7_info, FLAG_CKT_LC_UNBLK_RX)) { - SS7_WARN("Received local UBL on circuit that is already unblocked!\n"); - } - - /* throw the ckt block flag */ - sngss7_set_flag(sngss7_info, FLAG_CKT_LC_UNBLK_RX); - - /* set the channel to suspended state */ - ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_SUSPENDED); - - /* unlock the channel again before we exit */ - ftdm_mutex_unlock(ftdmchan->mutex); - - SS7_FUNC_TRACE_EXIT(__FUNCTION__); - return FTDM_SUCCESS; -} - -/******************************************************************************/ -static ftdm_status_t handle_ucic(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, uint8_t globalFlg, uint8_t evntType, SiStaEvnt *siStaEvnt) -{ - SS7_FUNC_TRACE_ENTER(__FUNCTION__); - - sngss7_chan_data_t *sngss7_info = NULL; - ftdm_channel_t *ftdmchan = NULL; - - /* get the ftdmchan and ss7_chan_data from the circuit */ - if (extract_chan_data(circuit, &sngss7_info, &ftdmchan)) { - SS7_ERROR("Failed to extract channel data for circuit = %d!\n", circuit); - SS7_FUNC_TRACE_EXIT(__FUNCTION__); - return FTDM_FAIL; - } - - /* now that we have the right channel...put a lock on it so no-one else can use it */ - ftdm_mutex_lock(ftdmchan->mutex); - - /* check if there is a pending state change, give it a bit to clear */ - if (check_for_state_change(ftdmchan)) { - SS7_ERROR("Failed to wait for pending state change on CIC = %d\n", sngss7_info->circuit->cic); - ftdm_mutex_unlock(ftdmchan->mutex); - SS7_FUNC_TRACE_EXIT(__FUNCTION__); - SS7_ASSERT; - }; - - /* throw the ckt block flag */ - sngss7_set_flag(sngss7_info, FLAG_CKT_UCIC_BLOCK); - - /* set the channel to suspended state */ - ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_SUSPENDED); - - /* unlock the channel again before we exit */ - ftdm_mutex_unlock(ftdmchan->mutex); - - SS7_FUNC_TRACE_EXIT(__FUNCTION__); - return FTDM_SUCCESS; -} - - -/******************************************************************************/ -#if 0 -{ - SS7_FUNC_TRACE_ENTER(__FUNCTION__); - - sngss7_chan_data_t *sngss7_info = NULL; - ftdm_channel_t *ftdmchan = NULL; - - /* get the ftdmchan and ss7_chan_data from the circuit */ - if (extract_chan_data(circuit, &sngss7_info, &ftdmchan)) { - SS7_ERROR("Failed to extract channel data for circuit = %d!\n", circuit); - SS7_FUNC_TRACE_EXIT(__FUNCTION__); - return FTDM_FAIL; - } - - /* now that we have the right channel...put a lock on it so no-one else can use it */ - ftdm_mutex_lock(ftdmchan->mutex); - - /* check if there is a pending state change, give it a bit to clear */ - if (check_for_state_change(ftdmchan)) { - SS7_ERROR("Failed to wait for pending state change on CIC = %d\n", sngss7_info->circuit->cic); - ftdm_mutex_unlock(ftdmchan->mutex); - SS7_FUNC_TRACE_EXIT(__FUNCTION__); - return FTDM_FAIL; - }; - - /* fill in here */ - - /* unlock the channel again before we exit */ - ftdm_mutex_unlock(ftdmchan->mutex); - - SS7_FUNC_TRACE_EXIT(__FUNCTION__); - return FTDM_SUCCESS; -} - -/******************************************************************************/ -#endif /******************************************************************************/ /******************************************************************************/ diff --git a/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_main.c b/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_main.c index fc2c1a66b7..a9851bda3f 100644 --- a/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_main.c +++ b/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_main.c @@ -46,7 +46,8 @@ ftdm_sngss7_data_t g_ftdm_sngss7_data; /* PROTOTYPES *****************************************************************/ static void *ftdm_sangoma_ss7_run (ftdm_thread_t * me, void *obj); -static void ftdm_sangoma_ss7_process_state_change (ftdm_channel_t * ftdmchan); +static void ftdm_sangoma_ss7_process_state_change (ftdm_channel_t *ftdmchan); +static void ftdm_sangoma_ss7_process_stack_event (sngss7_event_data_t *sngss7_event); static ftdm_status_t ftdm_sangoma_ss7_stop (ftdm_span_t * span); static ftdm_status_t ftdm_sangoma_ss7_start (ftdm_span_t * span); @@ -268,11 +269,12 @@ ftdm_state_map_t sangoma_ss7_state_map = { /* MONITIOR THREADS ***********************************************************/ static void *ftdm_sangoma_ss7_run(ftdm_thread_t * me, void *obj) { - ftdm_interrupt_t *ftdm_sangoma_ss7_int = NULL; + ftdm_interrupt_t *ftdm_sangoma_ss7_int[2]; ftdm_span_t *ftdmspan = (ftdm_span_t *) obj; ftdm_channel_t *ftdmchan = NULL; sngss7_chan_data_t *sngss7_info = NULL; - sngss7_span_data_t *sngss7_span = NULL; + sngss7_event_data_t *sngss7_event = NULL; + sngss7_span_data_t *sngss7_span = (sngss7_span_data_t *)ftdmspan->mod_data; int i; ftdm_log (FTDM_LOG_INFO, "ftmod_sangoma_ss7 monitor thread for span=%u started.\n", ftdmspan->span_id); @@ -280,31 +282,53 @@ static void *ftdm_sangoma_ss7_run(ftdm_thread_t * me, void *obj) /* set IN_THREAD flag so that we know this thread is running */ ftdm_set_flag (ftdmspan, FTDM_SPAN_IN_THREAD); - /* get an interrupt queue for this span */ - if (ftdm_queue_get_interrupt (ftdmspan->pendingchans, &ftdm_sangoma_ss7_int) != FTDM_SUCCESS) { - SS7_CRITICAL ("Failed to get a ftdm_interrupt for span = %d!\n", ftdmspan->span_id); + /* get an interrupt queue for this span for channel state changes */ + if (ftdm_queue_get_interrupt (ftdmspan->pendingchans, &ftdm_sangoma_ss7_int[0]) != FTDM_SUCCESS) { + SS7_CRITICAL ("Failed to get a ftdm_interrupt for span = %d for channel state changes!\n", ftdmspan->span_id); + goto ftdm_sangoma_ss7_run_exit; + } + + /* get an interrupt queue for this span for Trillium events */ + if (ftdm_queue_get_interrupt (sngss7_span->event_queue, &ftdm_sangoma_ss7_int[1]) != FTDM_SUCCESS) { + SS7_CRITICAL ("Failed to get a ftdm_interrupt for span = %d for Trillium event queue!\n", ftdmspan->span_id); goto ftdm_sangoma_ss7_run_exit; } while (ftdm_running () && !(ftdm_test_flag (ftdmspan, FTDM_SPAN_STOP_THREAD))) { - /* find out why we returned from the interrupt queue */ - switch ((ftdm_interrupt_wait (ftdm_sangoma_ss7_int, 100))) { + /* check the channel state queue for an event*/ + switch ((ftdm_interrupt_multiple_wait(ftdm_sangoma_ss7_int, 2, 100))) { /**********************************************************************/ - case FTDM_SUCCESS: /* there was a state change on the span */ - /* process all pending state changes */ + case FTDM_SUCCESS: /* process all pending state changes */ + /* clean out all pending channel state changes */ while ((ftdmchan = ftdm_queue_dequeue (ftdmspan->pendingchans))) { /* double check that this channel has a state change pending */ if (ftdm_test_flag (ftdmchan, FTDM_CHANNEL_STATE_CHANGE)) { + /*first lock the channel */ + ftdm_mutex_lock(ftdmchan->mutex); + ftdm_sangoma_ss7_process_state_change (ftdmchan); + + /* unlock the channel */ + ftdm_mutex_unlock (ftdmchan->mutex); } else { - SS7_ERROR("ftdm_core reported state change, but state change flag not set on ft-span = %d, ft-chan = %d\n", + /* since we handle state changes again after handling the trillium queue + * this can occur since we'll clear the flag for the event but can't pop + * the channel out of pendingchans + */ +/* SS7_ERROR("ftdm_core reported state change, but state change flag not set on ft-span = %d, ft-chan = %d\n", ftdmchan->physical_span_id, - ftdmchan->physical_chan_id); + ftdmchan->physical_chan_id);*/ } }/* while ((ftdmchan = ftdm_queue_dequeue(ftdmspan->pendingchans))) */ + /* clean out all pending stack events */ + while ((sngss7_event = ftdm_queue_dequeue(sngss7_span->event_queue))) { + ftdm_sangoma_ss7_process_stack_event(sngss7_event); + ftdm_safe_free(sngss7_event); + }/* while ((sngss7_event = ftdm_queue_dequeue(ftdmspan->signal_data->event_queue))) */ + break; /**********************************************************************/ case FTDM_TIMEOUT: @@ -412,6 +436,81 @@ ftdm_sangoma_ss7_run_exit: return NULL; } +/******************************************************************************/ +static void ftdm_sangoma_ss7_process_stack_event (sngss7_event_data_t *sngss7_event) +{ + sngss7_chan_data_t *sngss7_info ; + ftdm_channel_t *ftdmchan; + + /* get the ftdmchan and ss7_chan_data from the circuit */ + if (extract_chan_data(sngss7_event->circuit, &sngss7_info, &ftdmchan)) { + SS7_ERROR("Failed to extract channel data for circuit = %d!\n", sngss7_event->circuit); + return; + } + + /* now that we have the right channel...put a lock on it so no-one else can use it */ + ftdm_mutex_lock(ftdmchan->mutex); + + /* figure out the type of event and send it to the right handler */ + switch (sngss7_event->event_id) { + /**************************************************************************/ + case (SNGSS7_CON_IND_EVENT): + handle_con_ind(sngss7_event->suInstId, sngss7_event->spInstId, sngss7_event->circuit, &sngss7_event->event.siConEvnt); + break; + /**************************************************************************/ + case (SNGSS7_CON_CFM_EVENT): + handle_con_cfm(sngss7_event->suInstId, sngss7_event->spInstId, sngss7_event->circuit, &sngss7_event->event.siConEvnt); + break; + /**************************************************************************/ + case (SNGSS7_CON_STA_EVENT): + handle_con_sta(sngss7_event->suInstId, sngss7_event->spInstId, sngss7_event->circuit, &sngss7_event->event.siCnStEvnt, sngss7_event->evntType); + break; + /**************************************************************************/ + case (SNGSS7_REL_IND_EVENT): + handle_rel_ind(sngss7_event->suInstId, sngss7_event->spInstId, sngss7_event->circuit, &sngss7_event->event.siRelEvnt); + break; + /**************************************************************************/ + case (SNGSS7_REL_CFM_EVENT): + handle_rel_cfm(sngss7_event->suInstId, sngss7_event->spInstId, sngss7_event->circuit, &sngss7_event->event.siRelEvnt); + break; + /**************************************************************************/ + case (SNGSS7_DAT_IND_EVENT): + handle_dat_ind(sngss7_event->suInstId, sngss7_event->spInstId, sngss7_event->circuit, &sngss7_event->event.siInfoEvnt); + break; + /**************************************************************************/ + case (SNGSS7_FAC_IND_EVENT): + handle_fac_ind(sngss7_event->suInstId, sngss7_event->spInstId, sngss7_event->circuit, sngss7_event->evntType, &sngss7_event->event.siFacEvnt); + break; + /**************************************************************************/ + case (SNGSS7_FAC_CFM_EVENT): + handle_fac_cfm(sngss7_event->suInstId, sngss7_event->spInstId, sngss7_event->circuit, sngss7_event->evntType, &sngss7_event->event.siFacEvnt); + break; + /**************************************************************************/ + case (SNGSS7_UMSG_IND_EVENT): + handle_umsg_ind(sngss7_event->suInstId, sngss7_event->spInstId, sngss7_event->circuit); + break; + /**************************************************************************/ + case (SNGSS7_STA_IND_EVENT): + handle_sta_ind(sngss7_event->suInstId, sngss7_event->spInstId, sngss7_event->circuit, sngss7_event->globalFlg, sngss7_event->evntType, &sngss7_event->event.siStaEvnt); + break; + /**************************************************************************/ + default: + SS7_ERROR("Unknown Event Id!\n"); + break; + /**************************************************************************/ + } /* switch (sngss7_event->event_id) */ + + /* while there's a state change present on this channel process it */ + while (ftdm_test_flag(ftdmchan, FTDM_CHANNEL_STATE_CHANGE)) { + ftdm_sangoma_ss7_process_state_change(ftdmchan); + } + + /* unlock the channel */ + ftdm_mutex_unlock(ftdmchan->mutex); + + return; +} + /******************************************************************************/ static void ftdm_sangoma_ss7_process_state_change (ftdm_channel_t * ftdmchan) { @@ -426,9 +525,6 @@ static void ftdm_sangoma_ss7_process_state_change (ftdm_channel_t * ftdmchan) sigev.span_id = ftdmchan->span_id; sigev.channel = ftdmchan; - /*first lock the channel */ - ftdm_mutex_lock (ftdmchan->mutex); - SS7_DEBUG_CHAN(ftdmchan, "ftmod_sangoma_ss7 processing state %s\n", ftdm_channel_state2str (ftdmchan->state)); /* clear the state change flag...since we might be setting a new state */ @@ -1052,9 +1148,6 @@ suspend_goto_restart: /**************************************************************************/ }/*switch (ftdmchan->state) */ - /*unlock */ - ftdm_mutex_unlock (ftdmchan->mutex); - return; } @@ -1254,7 +1347,7 @@ static ftdm_status_t ftdm_sangoma_ss7_stop(ftdm_span_t * span) /* SIG_FUNCTIONS ***************************************************************/ static FIO_CONFIGURE_SPAN_SIGNALING_FUNCTION(ftdm_sangoma_ss7_span_config) { - sngss7_span_data_t *ss7_span_info; + sngss7_span_data_t *ss7_span_info; ftdm_log (FTDM_LOG_INFO, "Configuring ftmod_sangoma_ss7 span = %s(%d)...\n", span->name, @@ -1264,29 +1357,20 @@ static FIO_CONFIGURE_SPAN_SIGNALING_FUNCTION(ftdm_sangoma_ss7_span_config) ss7_span_info = ftdm_calloc (1, sizeof (sngss7_span_data_t)); /* create a timer schedule */ - if (ftdm_sched_create (&ss7_span_info->sched, "SngSS7_Schedule")) { - SS7_CRITICAL ("Unable to create timer schedule!\n"); + if (ftdm_sched_create(&ss7_span_info->sched, "SngSS7_Schedule")) { + SS7_CRITICAL("Unable to create timer schedule!\n"); return FTDM_FAIL; } /* start the free run thread for the schedule */ - if (ftdm_sched_free_run (ss7_span_info->sched)) { - SS7_CRITICAL ("Unable to schedule free run!\n"); + if (ftdm_sched_free_run(ss7_span_info->sched)) { + SS7_CRITICAL("Unable to schedule free run!\n"); return FTDM_FAIL; } - /* attach the span info to the span */ - span->mod_data = ss7_span_info; - - /* parse the configuration and apply to the global config structure */ - if (ftmod_ss7_parse_xml(ftdm_parameters, span)) { - ftdm_log (FTDM_LOG_CRIT, "Failed to parse configuration!\n"); - return FTDM_FAIL; - } - - /* configure libsngss7 */ - if (ft_to_sngss7_cfg_all()) { - ftdm_log (FTDM_LOG_CRIT, "Failed to configure LibSngSS7!\n"); + /* create an event queue for this span */ + if ((ftdm_queue_create(&(ss7_span_info)->event_queue, SNGSS7_EVENT_QUEUE_SIZE)) != FTDM_SUCCESS) { + SS7_CRITICAL("Unable to create event queue!\n"); return FTDM_FAIL; } @@ -1302,9 +1386,22 @@ static FIO_CONFIGURE_SPAN_SIGNALING_FUNCTION(ftdm_sangoma_ss7_span_config) span->get_channel_sig_status = ftdm_sangoma_ss7_get_sig_status; span->set_channel_sig_status = ftdm_sangoma_ss7_set_sig_status; span->state_map = &sangoma_ss7_state_map; + span->mod_data = ss7_span_info; ftdm_set_flag (span, FTDM_SPAN_USE_CHAN_QUEUE); + /* parse the configuration and apply to the global config structure */ + if (ftmod_ss7_parse_xml(ftdm_parameters, span)) { + ftdm_log (FTDM_LOG_CRIT, "Failed to parse configuration!\n"); + return FTDM_FAIL; + } + + /* configure libsngss7 */ + if (ft_to_sngss7_cfg_all()) { + ftdm_log (FTDM_LOG_CRIT, "Failed to configure LibSngSS7!\n"); + return FTDM_FAIL; + } + ftdm_log (FTDM_LOG_INFO, "Finished configuring ftmod_sangoma_ss7 span = %s(%d)...\n", span->name, span->span_id); @@ -1336,7 +1433,7 @@ static FIO_SIG_LOAD_FUNCTION(ftdm_sangoma_ss7_init) /* message (IAM, ACM, ANM, etc) trace initizalation */ g_ftdm_sngss7_data.message_trace = 1; - g_ftdm_sngss7_data.message_trace_level = 7; + g_ftdm_sngss7_data.message_trace_level = 6; /* setup the call backs needed by Sangoma_SS7 library */ sng_event.cc.sng_con_ind = sngss7_con_ind; diff --git a/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_main.h b/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_main.h index 6bfc38e588..3bf12ae307 100644 --- a/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_main.h +++ b/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_main.h @@ -50,12 +50,26 @@ /******************************************************************************/ /* DEFINES ********************************************************************/ -#define MAX_NAME_LEN 10 -#define MAX_PATH 255 +#define MAX_NAME_LEN 10 +#define MAX_PATH 255 -#define MAX_CIC_LENGTH 5 -#define MAX_CIC_MAP_LENGTH 1000 +#define MAX_CIC_LENGTH 5 +#define MAX_CIC_MAP_LENGTH 1000 +#define SNGSS7_EVENT_QUEUE_SIZE 100 + +typedef enum { + SNGSS7_CON_IND_EVENT = 0, + SNGSS7_CON_CFM_EVENT, + SNGSS7_CON_STA_EVENT, + SNGSS7_REL_IND_EVENT, + SNGSS7_REL_CFM_EVENT, + SNGSS7_DAT_IND_EVENT, + SNGSS7_FAC_IND_EVENT, + SNGSS7_FAC_CFM_EVENT, + SNGSS7_UMSG_IND_EVENT, + SNGSS7_STA_IND_EVENT +} sng_event_type_t; typedef enum { VOICE = 0, @@ -334,8 +348,31 @@ typedef struct sngss7_chan_data { typedef struct sngss7_span_data { ftdm_sched_t *sched; sngss7_group_data_t grs; + ftdm_queue_t *event_queue; }sngss7_span_data_t; +typedef struct sngss7_event_data +{ + uint32_t event_id; + uint32_t spId; + uint32_t suId; + uint32_t spInstId; + uint32_t suInstId; + uint32_t circuit; + uint8_t globalFlg; + uint8_t evntType; + union + { + SiConEvnt siConEvnt; + SiCnStEvnt siCnStEvnt; + SiRelEvnt siRelEvnt; + SiInfoEvnt siInfoEvnt; + SiFacEvnt siFacEvnt; + SiStaEvnt siStaEvnt; + } event; +} sngss7_event_data_t; + + typedef enum { @@ -441,6 +478,36 @@ void sngss7_fac_cfm(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, uint void sngss7_sta_ind(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, uint8_t globalFlg, uint8_t evntType, SiStaEvnt *siStaEvnt); void sngss7_umsg_ind(uint32_t suInstId, uint32_t spInstId, uint32_t circuit); +ftdm_status_t handle_con_ind(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, SiConEvnt *siConEvnt); +ftdm_status_t handle_con_sta(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, SiCnStEvnt *siCnStEvnt, uint8_t evntType); +ftdm_status_t handle_con_cfm(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, SiConEvnt *siConEvnt); +ftdm_status_t handle_rel_ind(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, SiRelEvnt *siRelEvnt); +ftdm_status_t handle_rel_cfm(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, SiRelEvnt *siRelEvnt); +ftdm_status_t handle_dat_ind(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, SiInfoEvnt *siInfoEvnt); +ftdm_status_t handle_fac_ind(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, uint8_t evntType, SiFacEvnt *siFacEvnt); +ftdm_status_t handle_fac_cfm(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, uint8_t evntType, SiFacEvnt *siFacEvnt); +ftdm_status_t handle_umsg_ind(uint32_t suInstId, uint32_t spInstId, uint32_t circuit); +ftdm_status_t handle_sta_ind(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, uint8_t globalFlg, uint8_t evntType, SiStaEvnt *siStaEvnt); + +ftdm_status_t handle_reattempt(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, uint8_t globalFlg, uint8_t evntType, SiStaEvnt *siStaEvnt); +ftdm_status_t handle_pause(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, uint8_t globalFlg, uint8_t evntType, SiStaEvnt *siStaEvnt); +ftdm_status_t handle_resume(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, uint8_t globalFlg, uint8_t evntType, SiStaEvnt *siStaEvnt); +ftdm_status_t handle_cot_start(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, uint8_t globalFlg, uint8_t evntType, SiStaEvnt *siStaEvnt); +ftdm_status_t handle_cot_stop(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, uint8_t globalFlg, uint8_t evntType, SiStaEvnt *siStaEvnt); +ftdm_status_t handle_cot(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, uint8_t globalFlg, uint8_t evntType, SiStaEvnt *siStaEvnt); +ftdm_status_t handle_rsc_req(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, uint8_t globalFlg, uint8_t evntType, SiStaEvnt *siStaEvnt); +ftdm_status_t handle_local_rsc_req(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, uint8_t globalFlg, uint8_t evntType, SiStaEvnt *siStaEvnt); +ftdm_status_t handle_rsc_rsp(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, uint8_t globalFlg, uint8_t evntType, SiStaEvnt *siStaEvnt); +ftdm_status_t handle_grs_req(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, uint8_t globalFlg, uint8_t evntType, SiStaEvnt *siStaEvnt); +ftdm_status_t handle_grs_rsp(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, uint8_t globalFlg, uint8_t evntType, SiStaEvnt *siStaEvnt); +ftdm_status_t handle_blo_req(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, uint8_t globalFlg, uint8_t evntType, SiStaEvnt *siStaEvnt); +ftdm_status_t handle_blo_rsp(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, uint8_t globalFlg, uint8_t evntType, SiStaEvnt *siStaEvnt); +ftdm_status_t handle_ubl_req(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, uint8_t globalFlg, uint8_t evntType, SiStaEvnt *siStaEvnt); +ftdm_status_t handle_ubl_rsp(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, uint8_t globalFlg, uint8_t evntType, SiStaEvnt *siStaEvnt); +ftdm_status_t handle_local_blk(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, uint8_t globalFlg, uint8_t evntType, SiStaEvnt *siStaEvnt); +ftdm_status_t handle_local_ubl(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, uint8_t globalFlg, uint8_t evntType, SiStaEvnt *siStaEvnt); +ftdm_status_t handle_ucic(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, uint8_t globalFlg, uint8_t evntType, SiStaEvnt *siStaEvnt); + uint8_t copy_cgPtyNum_from_sngss7(ftdm_caller_data_t *ftdm, SiCgPtyNum *cgPtyNum); uint8_t copy_cgPtyNum_to_sngss7(ftdm_caller_data_t *ftdm, SiCgPtyNum *cgPtyNum); uint8_t copy_cdPtyNum_from_sngss7(ftdm_caller_data_t *ftdm, SiCdPtyNum *cdPtyNum); From e15d52bd80b29327617b52c7f382f3f4cb8f7228 Mon Sep 17 00:00:00 2001 From: Konrad Hammel Date: Wed, 1 Sep 2010 12:44:28 -0400 Subject: [PATCH 06/10] freetdm: ss7 - updated to allow TMR/bearer cap pass-through --- .../ftmod_sangoma_ss7_handle.c | 78 +++++++---- .../ftmod_sangoma_ss7/ftmod_sangoma_ss7_out.c | 130 +++++++++--------- 2 files changed, 117 insertions(+), 91 deletions(-) diff --git a/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_handle.c b/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_handle.c index d1f3a8b89c..a0bf95b09c 100644 --- a/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_handle.c +++ b/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_handle.c @@ -41,7 +41,6 @@ /* GLOBALS ********************************************************************/ /******************************************************************************/ -/* PROTOTYPES *****************************************************************/ /* PROTOTYPES *****************************************************************/ ftdm_status_t handle_con_ind(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, SiConEvnt *siConEvnt); ftdm_status_t handle_con_sta(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, SiCnStEvnt *siCnStEvnt, uint8_t evntType); @@ -140,43 +139,68 @@ ftdm_status_t handle_con_ind(uint32_t suInstId, uint32_t spInstId, uint32_t circ } else { - /* fill in cid/ani number */ - if (siConEvnt->cgPtyNum.addrSig.pres) { - copy_tknStr_from_sngss7(siConEvnt->cgPtyNum.addrSig, - ftdmchan->caller_data.cid_num.digits, - siConEvnt->cgPtyNum.oddEven); + /* fill in calling party information */ + if (siConEvnt->cgPtyNum.eh.pres) { + if (siConEvnt->cgPtyNum.addrSig.pres) { + /* fill in cid_num */ + copy_tknStr_from_sngss7(siConEvnt->cgPtyNum.addrSig, + ftdmchan->caller_data.cid_num.digits, + siConEvnt->cgPtyNum.oddEven); - /* fill in cid Name */ - ftdm_set_string(ftdmchan->caller_data.cid_name, ftdmchan->caller_data.cid_num.digits); + /* fill in cid Name */ + ftdm_set_string(ftdmchan->caller_data.cid_name, ftdmchan->caller_data.cid_num.digits); - ftdm_set_string(ftdmchan->caller_data.ani.digits, ftdmchan->caller_data.cid_num.digits); + /* fill in ANI */ + ftdm_set_string(ftdmchan->caller_data.ani.digits, ftdmchan->caller_data.cid_num.digits); + } + if (siConEvnt->cgPtyNum.scrnInd.pres) { + /* fill in the screening indication value */ + ftdmchan->caller_data.screen = siConEvnt->cgPtyNum.scrnInd.val; + } + + if (siConEvnt->cgPtyNum.presRest.pres) { + /* fill in the presentation value */ + ftdmchan->caller_data.pres = siConEvnt->cgPtyNum.presRest.val; + } } else { - SS7_INFO("No Calling party (ANI) information in IAM!\n"); + SS7_INFO_CHAN(ftdmchan,"No Calling party (ANI) information in IAM!%s\n", " "); } - /* fill in dnis */ - if (siConEvnt->cdPtyNum.addrSig.pres) { - copy_tknStr_from_sngss7(siConEvnt->cdPtyNum.addrSig, - ftdmchan->caller_data.dnis.digits, - siConEvnt->cdPtyNum.oddEven); + /* fill in called party infomation */ + if (siConEvnt->cdPtyNum.eh.pres) { + if (siConEvnt->cdPtyNum.addrSig.pres) { + /* fill in the called number/dnis */ + copy_tknStr_from_sngss7(siConEvnt->cdPtyNum.addrSig, + ftdmchan->caller_data.dnis.digits, + siConEvnt->cdPtyNum.oddEven); + } + } else { + SS7_INFO_CHAN(ftdmchan,"No Called party (DNIS) information in IAM!%s\n", " "); + } + + /* fill in rdnis information*/ + if (siConEvnt->redirgNum.eh.pres) { + if (siConEvnt->redirgNum.addrSig.pres) { + /* fill in the rdnis digits */ + copy_tknStr_from_sngss7(siConEvnt->redirgNum.addrSig, + ftdmchan->caller_data.rdnis.digits, + siConEvnt->cgPtyNum.oddEven); + } } else { - SS7_INFO("No Called party (DNIS) information in IAM!\n"); + SS7_DEBUG_CHAN(ftdmchan,"No RDNIS party information in IAM!%s\n", " "); } - /* fill in rdnis */ - if (siConEvnt->redirgNum.addrSig.pres) { - copy_tknStr_from_sngss7(siConEvnt->redirgNum.addrSig, - ftdmchan->caller_data.rdnis.digits, - siConEvnt->cgPtyNum.oddEven); - } else { - SS7_INFO("No RDNIS party information in IAM!\n"); + /* fill in the TMR/bearer capability */ + if (siConEvnt->txMedReq.eh.pres) { + if (siConEvnt->txMedReq.trMedReq.pres) { + /* fill in the bearer type */ + ftdmchan->caller_data.bearer_capability = siConEvnt->txMedReq.trMedReq.val; + } + } else { + SS7_DEBUG_CHAN(ftdmchan,"No TMR/Bearer Cap information in IAM!%s\n", " "); } - /* fill in screening/presentation */ - ftdmchan->caller_data.screen = siConEvnt->cgPtyNum.scrnInd.val; - ftdmchan->caller_data.pres = siConEvnt->cgPtyNum.presRest.val; - /* set the state of the channel to collecting...the rest is done by the chan monitor */ ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_COLLECT); diff --git a/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_out.c b/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_out.c index 53d0f9d937..600a52910c 100644 --- a/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_out.c +++ b/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_out.c @@ -64,70 +64,72 @@ void ft_to_sngss7_grs (ftdm_channel_t * ftdmchan); void ft_to_sngss7_iam (ftdm_channel_t * ftdmchan) { - SS7_FUNC_TRACE_ENTER (__FUNCTION__); - - sngss7_chan_data_t *sngss7_info = ftdmchan->call_data;; - SiConEvnt iam; - - sngss7_info->suInstId = get_unique_id (); - sngss7_info->spInstId = 0; - sngss7_info->spId = 1; - - memset (&iam, 0x0, sizeof (iam)); - - /* copy down the nature of connection indicators */ - iam.natConInd.eh.pres = PRSNT_NODEF; - iam.natConInd.satInd.pres = PRSNT_NODEF; - iam.natConInd.satInd.val = 0; - iam.natConInd.contChkInd.pres = PRSNT_NODEF; - iam.natConInd.contChkInd.val = 0x00; - iam.natConInd.echoCntrlDevInd.pres = PRSNT_NODEF; - iam.natConInd.echoCntrlDevInd.val = 0x01; - - /* copy down the forward call indicators */ - iam.fwdCallInd.eh.pres = PRSNT_NODEF; - iam.fwdCallInd.natIntCallInd.pres = PRSNT_NODEF; - iam.fwdCallInd.natIntCallInd.val = 0x00; - iam.fwdCallInd.end2EndMethInd.pres = PRSNT_NODEF; - iam.fwdCallInd.end2EndMethInd.val = 0x00; - iam.fwdCallInd.intInd.pres = PRSNT_NODEF; - iam.fwdCallInd.intInd.val = 0x01; - iam.fwdCallInd.end2EndInfoInd.pres = PRSNT_NODEF; - iam.fwdCallInd.end2EndInfoInd.val = 0x00; - iam.fwdCallInd.isdnUsrPrtInd.pres = PRSNT_NODEF; - iam.fwdCallInd.isdnUsrPrtInd.val = 0x01; - iam.fwdCallInd.isdnUsrPrtPrfInd.pres = PRSNT_NODEF; - iam.fwdCallInd.isdnUsrPrtPrfInd.val = 0x02; - iam.fwdCallInd.isdnAccInd.pres = PRSNT_NODEF; - iam.fwdCallInd.isdnAccInd.val = 0x01; - iam.fwdCallInd.sccpMethInd.pres = PRSNT_NODEF; - iam.fwdCallInd.sccpMethInd.val = 0x00; - - /* copy down the calling number information */ - iam.cgPtyCat.eh.pres = PRSNT_NODEF; - iam.cgPtyCat.cgPtyCat.pres = PRSNT_NODEF; - iam.cgPtyCat.cgPtyCat.val = 0x0a; - - /* copy down the transmission medium requirements */ - iam.txMedReq.eh.pres = PRSNT_NODEF; - iam.txMedReq.trMedReq.pres = PRSNT_NODEF; - iam.txMedReq.trMedReq.val = 0; /* SPEECH = 0, 3.1Khz = 3, 64k unres = 2 */ - - /* copy down the called number information */ - copy_cdPtyNum_to_sngss7 (&ftdmchan->caller_data, &iam.cdPtyNum); - - /* copy down the calling number information */ - copy_cgPtyNum_to_sngss7 (&ftdmchan->caller_data, &iam.cgPtyNum); - - sng_cc_con_request (sngss7_info->spId, - sngss7_info->suInstId, - sngss7_info->spInstId, - sngss7_info->circuit->id, &iam, 0); - - SS7_MSG_TRACE(ftdmchan, sngss7_info, "Tx IAM\n"); - - SS7_FUNC_TRACE_EXIT (__FUNCTION__); - return; + SS7_FUNC_TRACE_ENTER (__FUNCTION__); + + sngss7_chan_data_t *sngss7_info = ftdmchan->call_data;; + SiConEvnt iam; + + sngss7_info->suInstId = get_unique_id (); + sngss7_info->spInstId = 0; + sngss7_info->spId = 1; + + memset (&iam, 0x0, sizeof (iam)); + + /* copy down the nature of connection indicators */ + iam.natConInd.eh.pres = PRSNT_NODEF; + iam.natConInd.satInd.pres = PRSNT_NODEF; + iam.natConInd.satInd.val = 0; /* no satellite circuit */ + iam.natConInd.contChkInd.pres = PRSNT_NODEF; + iam.natConInd.contChkInd.val = CONTCHK_NOTREQ; + iam.natConInd.echoCntrlDevInd.pres = PRSNT_NODEF; + iam.natConInd.echoCntrlDevInd.val = ECHOCDEV_INCL; + + /* copy down the forward call indicators */ + iam.fwdCallInd.eh.pres = PRSNT_NODEF; + iam.fwdCallInd.natIntCallInd.pres = PRSNT_NODEF; + iam.fwdCallInd.natIntCallInd.val = 0x00; + iam.fwdCallInd.end2EndMethInd.pres = PRSNT_NODEF; + iam.fwdCallInd.end2EndMethInd.val = E2EMTH_NOMETH; + iam.fwdCallInd.intInd.pres = PRSNT_NODEF; + iam.fwdCallInd.intInd.val = INTIND_NOINTW; + iam.fwdCallInd.end2EndInfoInd.pres = PRSNT_NODEF; + iam.fwdCallInd.end2EndInfoInd.val = E2EINF_NOINFO; + iam.fwdCallInd.isdnUsrPrtInd.pres = PRSNT_NODEF; + iam.fwdCallInd.isdnUsrPrtInd.val = ISUP_USED; + iam.fwdCallInd.isdnUsrPrtPrfInd.pres = PRSNT_NODEF; + iam.fwdCallInd.isdnUsrPrtPrfInd.val = PREF_REQAW; + iam.fwdCallInd.isdnAccInd.pres = PRSNT_NODEF; + iam.fwdCallInd.isdnAccInd.val = ISDNACC_ISDN; + iam.fwdCallInd.sccpMethInd.pres = PRSNT_NODEF; + iam.fwdCallInd.sccpMethInd.val = SCCPMTH_NOIND; + + /* copy down the calling number information */ + iam.cgPtyCat.eh.pres = PRSNT_NODEF; + iam.cgPtyCat.cgPtyCat.pres = PRSNT_NODEF; + iam.cgPtyCat.cgPtyCat.val = CAT_ORD; /* ordinary suscriber */ + + /* copy down the transmission medium requirements */ + iam.txMedReq.eh.pres = PRSNT_NODEF; + iam.txMedReq.trMedReq.pres = PRSNT_NODEF; + iam.txMedReq.trMedReq.val = ftdmchan->caller_data.bearer_capability; + + /* copy down the called number information */ + copy_cdPtyNum_to_sngss7 (&ftdmchan->caller_data, &iam.cdPtyNum); + + /* copy down the calling number information */ + copy_cgPtyNum_to_sngss7 (&ftdmchan->caller_data, &iam.cgPtyNum); + + sng_cc_con_request (sngss7_info->spId, + sngss7_info->suInstId, + sngss7_info->spInstId, + sngss7_info->circuit->id, + &iam, + 0); + + SS7_MSG_TRACE(ftdmchan, sngss7_info, "Tx IAM\n"); + + SS7_FUNC_TRACE_EXIT (__FUNCTION__); + return; } /******************************************************************************/ From 432e9cdf5b1606cd81cc1e78d5958ccaf7ed1d7c Mon Sep 17 00:00:00 2001 From: David Yat Sin Date: Wed, 1 Sep 2010 15:04:09 -0400 Subject: [PATCH 07/10] Added passthrough for bearer capability --- libs/freetdm/mod_freetdm/mod_freetdm.c | 4 + libs/freetdm/src/ftdm_call_utils.c | 31 ++++++ libs/freetdm/src/ftdm_io.c | 8 ++ .../ftmod_sangoma_isdn/ftmod_sangoma_isdn.h | 5 + .../ftmod_sangoma_isdn_cfg.c | 17 +++ .../ftmod_sangoma_isdn_stack_hndl.c | 24 ++-- .../ftmod_sangoma_isdn_stack_out.c | 34 +++--- .../ftmod_sangoma_isdn_support.c | 104 ++++++++++++++---- libs/freetdm/src/include/freetdm.h | 3 + .../src/include/private/ftdm_call_utils.h | 2 + 10 files changed, 184 insertions(+), 48 deletions(-) diff --git a/libs/freetdm/mod_freetdm/mod_freetdm.c b/libs/freetdm/mod_freetdm/mod_freetdm.c index 50eb7a2c4d..0d986f35a6 100755 --- a/libs/freetdm/mod_freetdm/mod_freetdm.c +++ b/libs/freetdm/mod_freetdm/mod_freetdm.c @@ -1230,10 +1230,14 @@ static switch_call_cause_t channel_outgoing_channel(switch_core_session_t *sessi freetdmvar = switch_channel_get_variable(channel, "freetdm_bearer_capability"); if (freetdmvar) { caller_data.bearer_capability = (uint8_t)atoi(freetdmvar); + } else { + caller_data.bearer_capability = FTDM_INVALID_INT_PARM; } freetdmvar = switch_channel_get_variable(channel, "freetdm_bearer_layer1"); if (freetdmvar) { caller_data.bearer_layer1 = (uint8_t)atoi(freetdmvar); + } else { + caller_data.bearer_layer1 = FTDM_INVALID_INT_PARM; } } diff --git a/libs/freetdm/src/ftdm_call_utils.c b/libs/freetdm/src/ftdm_call_utils.c index 4d7317ab22..d91b3bc9e2 100644 --- a/libs/freetdm/src/ftdm_call_utils.c +++ b/libs/freetdm/src/ftdm_call_utils.c @@ -78,6 +78,37 @@ FT_DECLARE(ftdm_status_t) ftdm_span_set_ton(const char *ton_string, uint8_t *tar return FTDM_SUCCESS; } +FT_DECLARE(ftdm_status_t) ftdm_span_set_bearer_capability(const char *bc_string, ftdm_bearer_cap_t *target) +{ + if (!strcasecmp(bc_string, "speech")) { + *target = FTDM_BEARER_CAP_SPEECH; + } else if (!strcasecmp(bc_string, "unrestricted-digital")) { + *target = FTDM_BEARER_CAP_64K_UNRESTRICTED; + } else if (!strcasecmp(bc_string, "3.1Khz")) { + *target = FTDM_BEARER_CAP_3_1KHZ_AUDIO; + } else { + ftdm_log(FTDM_LOG_WARNING, "Unsupported Bearer Capability value (%s)\n", bc_string); + return FTDM_FAIL; + } + return FTDM_SUCCESS; +} + +FT_DECLARE(ftdm_status_t) ftdm_span_set_bearer_layer1(const char *bc_string, ftdm_user_layer1_prot_t *target) +{ + if (!strcasecmp(bc_string, "v110")) { + *target = FTDM_USER_LAYER1_PROT_V110; + } else if (!strcasecmp(bc_string, "ulaw")) { + *target = FTDM_USER_LAYER1_PROT_ULAW; + } else if (!strcasecmp(bc_string, "alaw")) { + *target =FTDM_USER_LAYER1_PROT_ALAW ; + } else { + ftdm_log(FTDM_LOG_WARNING, "Unsupported Bearer Layer1 Prot value (%s)\n", bc_string); + return FTDM_FAIL; + } + return FTDM_SUCCESS; +} + + FT_DECLARE(ftdm_status_t) ftdm_is_number(char *number) { if (!number) { diff --git a/libs/freetdm/src/ftdm_io.c b/libs/freetdm/src/ftdm_io.c index 39eba67e8b..bfa9492060 100644 --- a/libs/freetdm/src/ftdm_io.c +++ b/libs/freetdm/src/ftdm_io.c @@ -293,6 +293,14 @@ static ftdm_status_t ftdm_set_caller_data(ftdm_span_t *span, ftdm_caller_data_t caller_data->rdnis.type = span->default_caller_data.rdnis.type; } + if (caller_data->bearer_capability == FTDM_INVALID_INT_PARM) { + caller_data->bearer_capability = span->default_caller_data.bearer_capability; + } + + if (caller_data->bearer_layer1 == FTDM_INVALID_INT_PARM) { + caller_data->bearer_layer1 = span->default_caller_data.bearer_layer1; + } + if (FTDM_FAIL == ftdm_is_number(caller_data->cid_num.digits)) { ftdm_log(FTDM_LOG_DEBUG, "dropping caller id number %s since we only accept digits\n", caller_data->cid_num.digits); caller_data->cid_num.digits[0] = '\0'; diff --git a/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn.h b/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn.h index 932db0e89e..3f63fbc1d4 100644 --- a/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn.h +++ b/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn.h @@ -320,6 +320,11 @@ void sngisdn_rcv_cc_ind(CcMngmt *status); void sngisdn_rcv_sng_log(uint8_t level, char *fmt,...); void sngisdn_rcv_sng_assert(char *message); +uint8_t sngisdn_get_infoTranCap_from_stack(ftdm_bearer_cap_t bearer_capability); +uint8_t sngisdn_get_usrInfoLyr1Prot_from_stack(ftdm_user_layer1_prot_t layer1_prot); +ftdm_bearer_cap_t sngisdn_get_infoTranCap_from_user(uint8_t bearer_capability); +ftdm_user_layer1_prot_t sngisdn_get_usrInfoLyr1Prot_from_user(uint8_t layer1_prot); + static __inline__ uint32_t sngisdn_test_flag(sngisdn_chan_data_t *sngisdn_info, sngisdn_flag_t flag) { return (uint32_t) sngisdn_info->flags & flag; diff --git a/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_cfg.c b/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_cfg.c index 6124070cad..ec44142303 100644 --- a/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_cfg.c +++ b/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_cfg.c @@ -163,6 +163,11 @@ ftdm_status_t ftmod_isdn_parse_cfg(ftdm_conf_parameter_t *ftdm_parameters, ftdm_ signal_data->overlap_dial = SNGISDN_OPT_DEFAULT; signal_data->setup_arb = SNGISDN_OPT_DEFAULT; + span->default_caller_data.bearer_capability = IN_ITC_SPEECH; + + /* Cannot set default bearer_layer1 yet, as we do not know the switchtype */ + span->default_caller_data.bearer_layer1 = FTDM_INVALID_INT_PARM; + if (span->trunk_type == FTDM_TRUNK_BRI || span->trunk_type == FTDM_TRUNK_BRI_PTMP) { @@ -240,6 +245,10 @@ ftdm_status_t ftmod_isdn_parse_cfg(ftdm_conf_parameter_t *ftdm_parameters, ftdm_ ftdm_span_set_ton(val, &span->default_caller_data.rdnis.type); } else if (!strcasecmp(var, "outbound-rdnis-npi")) { ftdm_span_set_npi(val, &span->default_caller_data.rdnis.plan); + } else if (!strcasecmp(var, "outbound-bearer_cap")) { + ftdm_span_set_bearer_capability(val, &span->default_caller_data.bearer_capability); + } else if (!strcasecmp(var, "outbound-bearer_layer1")) { + ftdm_span_set_bearer_layer1(val, &span->default_caller_data.bearer_layer1); } else { ftdm_log(FTDM_LOG_WARNING, "Ignoring unknown parameter %s\n", ftdm_parameters[paramindex].var); } @@ -253,6 +262,14 @@ ftdm_status_t ftmod_isdn_parse_cfg(ftdm_conf_parameter_t *ftdm_parameters, ftdm_ ftdm_log(FTDM_LOG_ERROR, "%s: signalling not specified", span->name); return FTDM_FAIL; } + + if (span->default_caller_data.bearer_layer1 == FTDM_INVALID_INT_PARM) { + if (signal_data->switchtype == SNGISDN_SWITCH_EUROISDN) { + span->default_caller_data.bearer_layer1 = IN_UIL1_G711ULAW; + } else { + span->default_caller_data.bearer_layer1 = IN_UIL1_G711ALAW; + } + } return FTDM_SUCCESS; } diff --git a/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_stack_hndl.c b/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_stack_hndl.c index 2520a3d9c3..f49d651c09 100644 --- a/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_stack_hndl.c +++ b/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_stack_hndl.c @@ -34,10 +34,10 @@ #include "ftmod_sangoma_isdn.h" -extern ftdm_status_t cpy_calling_num_from_sngisdn(ftdm_caller_data_t *ftdm, CgPtyNmb *cgPtyNmb); -extern ftdm_status_t cpy_called_num_from_sngisdn(ftdm_caller_data_t *ftdm, CdPtyNmb *cdPtyNmb); -extern ftdm_status_t cpy_redir_num_from_sngisdn(ftdm_caller_data_t *ftdm, RedirNmb *redirNmb); -extern ftdm_status_t cpy_calling_name_from_sngisdn(ftdm_caller_data_t *ftdm, Display *display); +extern ftdm_status_t cpy_calling_num_from_stack(ftdm_caller_data_t *ftdm, CgPtyNmb *cgPtyNmb); +extern ftdm_status_t cpy_called_num_from_stack(ftdm_caller_data_t *ftdm, CdPtyNmb *cdPtyNmb); +extern ftdm_status_t cpy_redir_num_from_stack(ftdm_caller_data_t *ftdm, RedirNmb *redirNmb); +extern ftdm_status_t cpy_calling_name_from_stack(ftdm_caller_data_t *ftdm, Display *display); /* Remote side transmit a SETUP */ void sngisdn_process_con_ind (sngisdn_event_data_t *sngisdn_event) @@ -110,10 +110,14 @@ void sngisdn_process_con_ind (sngisdn_event_data_t *sngisdn_event) break; } /* Fill in call information */ - cpy_calling_num_from_sngisdn(&ftdmchan->caller_data, &conEvnt->cgPtyNmb); - cpy_called_num_from_sngisdn(&ftdmchan->caller_data, &conEvnt->cdPtyNmb); - cpy_calling_name_from_sngisdn(&ftdmchan->caller_data, &conEvnt->display); + cpy_calling_num_from_stack(&ftdmchan->caller_data, &conEvnt->cgPtyNmb); + cpy_called_num_from_stack(&ftdmchan->caller_data, &conEvnt->cdPtyNmb); + cpy_calling_name_from_stack(&ftdmchan->caller_data, &conEvnt->display); + if (conEvnt->bearCap[0].eh.pres) { + ftdmchan->caller_data.bearer_layer1 = sngisdn_get_infoTranCap_from_stack(conEvnt->bearCap[0].usrInfoLyr1Prot.val); + ftdmchan->caller_data.bearer_capability = sngisdn_get_infoTranCap_from_stack(conEvnt->bearCap[0].infoTranCap.val); + } if (signal_data->switchtype == SNGISDN_SWITCH_NI2) { if (conEvnt->shift11.eh.pres && conEvnt->ni2OctStr.eh.pres) { @@ -370,7 +374,7 @@ void sngisdn_process_cnst_ind (sngisdn_event_data_t *sngisdn_event) ftdm_size_t min_digits = ((sngisdn_span_data_t*)ftdmchan->span->signal_data)->min_digits; ftdm_size_t num_digits; - cpy_called_num_from_sngisdn(&ftdmchan->caller_data, &cnStEvnt->cdPtyNmb); + cpy_called_num_from_stack(&ftdmchan->caller_data, &cnStEvnt->cdPtyNmb); num_digits = strlen(ftdmchan->caller_data.dnis.digits); if (cnStEvnt->sndCmplt.eh.pres || num_digits >= min_digits) { @@ -686,7 +690,6 @@ void sngisdn_process_fac_ind (sngisdn_event_data_t *sngisdn_event) switch (ftdmchan->state) { case FTDM_CHANNEL_STATE_GET_CALLERID: /* Update the caller ID Name */ -#if 1 if (facEvnt->facElmt.facStr.pres) { uint8_t facility_str[255]; memcpy(facility_str, (uint8_t*)&facEvnt->facElmt.facStr.val, facEvnt->facElmt.facStr.len); @@ -694,10 +697,7 @@ void sngisdn_process_fac_ind (sngisdn_event_data_t *sngisdn_event) if (sng_isdn_retrieve_facility_caller_name(facility_str, facEvnt->facElmt.facStr.len, retrieved_str) != FTDM_SUCCESS) { ftdm_log_chan_msg(ftdmchan, FTDM_LOG_WARNING, "Failed to retrieve Caller Name from Facility IE\n"); } - ftdm_log_chan(ftdmchan, FTDM_LOG_WARNING, "DYDBG Name is:%s\n", retrieved_str); } -#endif - ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_RING); break; default: diff --git a/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_stack_out.c b/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_stack_out.c index 8247735cb9..8ae513881b 100644 --- a/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_stack_out.c +++ b/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_stack_out.c @@ -34,9 +34,9 @@ #include "ftmod_sangoma_isdn.h" -extern ftdm_status_t cpy_calling_num_to_sngisdn(CgPtyNmb *cgPtyNmb, ftdm_caller_data_t *ftdm); -extern ftdm_status_t cpy_called_num_to_sngisdn(CdPtyNmb *cdPtyNmb, ftdm_caller_data_t *ftdm); -extern ftdm_status_t cpy_calling_name_to_sngisdn(ConEvnt *conEvnt, ftdm_channel_t *ftdmchan); +extern ftdm_status_t cpy_calling_num_from_user(CgPtyNmb *cgPtyNmb, ftdm_caller_data_t *ftdm); +extern ftdm_status_t cpy_called_num_from_user(CdPtyNmb *cdPtyNmb, ftdm_caller_data_t *ftdm); +extern ftdm_status_t cpy_calling_name_from_user(ConEvnt *conEvnt, ftdm_channel_t *ftdmchan); void sngisdn_snd_setup(ftdm_channel_t *ftdmchan); void sngisdn_snd_proceed(ftdm_channel_t *ftdmchan); @@ -62,11 +62,10 @@ void sngisdn_snd_setup(ftdm_channel_t *ftdmchan) ftdm_mutex_unlock(g_sngisdn_data.ccs[signal_data->cc_id].mutex); memset(&conEvnt, 0, sizeof(conEvnt)); - + conEvnt.bearCap[0].eh.pres = PRSNT_NODEF; conEvnt.bearCap[0].infoTranCap.pres = PRSNT_NODEF; - - conEvnt.bearCap[0].infoTranCap.val = IN_ITC_SPEECH; + conEvnt.bearCap[0].infoTranCap.val = sngisdn_get_infoTranCap_from_user(ftdmchan->caller_data.bearer_capability); conEvnt.bearCap[0].codeStand0.pres = PRSNT_NODEF; conEvnt.bearCap[0].codeStand0.val = IN_CSTD_CCITT; @@ -96,14 +95,21 @@ void sngisdn_snd_setup(ftdm_channel_t *ftdmchan) conEvnt.chanId.infoChanSel.val = ftdmchan->physical_chan_id; } else { /* PRI only params */ - - if (signal_data->switchtype == SNGISDN_SWITCH_EUROISDN) { - conEvnt.bearCap[0].usrInfoLyr1Prot.pres = PRSNT_NODEF; + conEvnt.bearCap[0].usrInfoLyr1Prot.pres = PRSNT_NODEF; + conEvnt.bearCap[0].usrInfoLyr1Prot.val = sngisdn_get_usrInfoLyr1Prot_from_user(ftdmchan->caller_data.bearer_layer1); + + if (signal_data->switchtype == SNGISDN_SWITCH_EUROISDN && + conEvnt.bearCap[0].usrInfoLyr1Prot.val == IN_UIL1_G711ULAW) { + + /* We are bridging a call from T1 */ conEvnt.bearCap[0].usrInfoLyr1Prot.val = IN_UIL1_G711ALAW; - } else { - conEvnt.bearCap[0].usrInfoLyr1Prot.pres = PRSNT_NODEF; + + } else if (conEvnt.bearCap[0].usrInfoLyr1Prot.val == IN_UIL1_G711ALAW) { + + /* We are bridging a call from E1 */ conEvnt.bearCap[0].usrInfoLyr1Prot.val = IN_UIL1_G711ULAW; } + conEvnt.bearCap[0].lyr1Ident.pres = PRSNT_NODEF; conEvnt.bearCap[0].lyr1Ident.val = IN_L1_IDENT; @@ -138,9 +144,9 @@ void sngisdn_snd_setup(ftdm_channel_t *ftdmchan) sngisdn_info->ces = CES_MNGMNT; } - cpy_called_num_to_sngisdn(&conEvnt.cdPtyNmb, &ftdmchan->caller_data); - cpy_calling_num_to_sngisdn(&conEvnt.cgPtyNmb, &ftdmchan->caller_data); - cpy_calling_name_to_sngisdn(&conEvnt, ftdmchan); + cpy_called_num_from_user(&conEvnt.cdPtyNmb, &ftdmchan->caller_data); + cpy_calling_num_from_user(&conEvnt.cgPtyNmb, &ftdmchan->caller_data); + cpy_calling_name_from_user(&conEvnt, ftdmchan); ftdm_log_chan(ftdmchan, FTDM_LOG_INFO, "Sending SETUP (suId:%d suInstId:%u spInstId:%u dchan:%d ces:%d)\n", signal_data->cc_id, sngisdn_info->suInstId, sngisdn_info->spInstId, signal_data->dchan_id, sngisdn_info->ces); diff --git a/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_support.c b/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_support.c index f910eb31eb..29e7994c87 100644 --- a/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_support.c +++ b/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_support.c @@ -34,15 +34,15 @@ #include "ftmod_sangoma_isdn.h" -ftdm_status_t cpy_calling_num_from_sngisdn(ftdm_caller_data_t *ftdm, CgPtyNmb *cgPtyNmb); -ftdm_status_t cpy_called_num_from_sngisdn(ftdm_caller_data_t *ftdm, CdPtyNmb *cdPtyNmb); -ftdm_status_t cpy_redir_num_from_sngisdn(ftdm_caller_data_t *ftdm, RedirNmb *redirNmb); -ftdm_status_t cpy_calling_name_from_sngisdn(ftdm_caller_data_t *ftdm, Display *display); +ftdm_status_t cpy_calling_num_from_stack(ftdm_caller_data_t *ftdm, CgPtyNmb *cgPtyNmb); +ftdm_status_t cpy_called_num_from_stack(ftdm_caller_data_t *ftdm, CdPtyNmb *cdPtyNmb); +ftdm_status_t cpy_redir_num_from_stack(ftdm_caller_data_t *ftdm, RedirNmb *redirNmb); +ftdm_status_t cpy_calling_name_from_stack(ftdm_caller_data_t *ftdm, Display *display); -ftdm_status_t cpy_calling_num_to_sngisdn(CgPtyNmb *cgPtyNmb, ftdm_caller_data_t *ftdm); -ftdm_status_t cpy_called_num_to_sngisdn(CdPtyNmb *cdPtyNmb, ftdm_caller_data_t *ftdm); -ftdm_status_t cpy_redir_num_to_sngisdn(RedirNmb *redirNmb, ftdm_caller_data_t *ftdm); -ftdm_status_t cpy_calling_name_to_sngisdn(ConEvnt *conEvnt, ftdm_channel_t *ftdmchan); +ftdm_status_t cpy_calling_num_from_user(CgPtyNmb *cgPtyNmb, ftdm_caller_data_t *ftdm); +ftdm_status_t cpy_called_num_from_user(CdPtyNmb *cdPtyNmb, ftdm_caller_data_t *ftdm); +ftdm_status_t cpy_redir_num_from_user(RedirNmb *redirNmb, ftdm_caller_data_t *ftdm); +ftdm_status_t cpy_calling_name_from_user(ConEvnt *conEvnt, ftdm_channel_t *ftdmchan); ftdm_status_t sngisdn_check_free_ids(void); @@ -146,7 +146,7 @@ ftdm_status_t sng_isdn_set_avail_rate(ftdm_span_t *ftdmspan, sngisdn_avail_t ava return FTDM_SUCCESS; } -ftdm_status_t cpy_calling_num_from_sngisdn(ftdm_caller_data_t *ftdm, CgPtyNmb *cgPtyNmb) +ftdm_status_t cpy_calling_num_from_stack(ftdm_caller_data_t *ftdm, CgPtyNmb *cgPtyNmb) { if (cgPtyNmb->eh.pres != PRSNT_NODEF) { return FTDM_FAIL; @@ -173,7 +173,7 @@ ftdm_status_t cpy_calling_num_from_sngisdn(ftdm_caller_data_t *ftdm, CgPtyNmb *c return FTDM_SUCCESS; } -ftdm_status_t cpy_called_num_from_sngisdn(ftdm_caller_data_t *ftdm, CdPtyNmb *cdPtyNmb) +ftdm_status_t cpy_called_num_from_stack(ftdm_caller_data_t *ftdm, CdPtyNmb *cdPtyNmb) { if (cdPtyNmb->eh.pres != PRSNT_NODEF) { return FTDM_FAIL; @@ -195,7 +195,7 @@ ftdm_status_t cpy_called_num_from_sngisdn(ftdm_caller_data_t *ftdm, CdPtyNmb *cd return FTDM_SUCCESS; } -ftdm_status_t cpy_redir_num_from_sngisdn(ftdm_caller_data_t *ftdm, RedirNmb *redirNmb) +ftdm_status_t cpy_redir_num_from_stack(ftdm_caller_data_t *ftdm, RedirNmb *redirNmb) { if (redirNmb->eh.pres != PRSNT_NODEF) { return FTDM_FAIL; @@ -215,7 +215,7 @@ ftdm_status_t cpy_redir_num_from_sngisdn(ftdm_caller_data_t *ftdm, RedirNmb *red return FTDM_SUCCESS; } -ftdm_status_t cpy_calling_name_from_sngisdn(ftdm_caller_data_t *ftdm, Display *display) +ftdm_status_t cpy_calling_name_from_stack(ftdm_caller_data_t *ftdm, Display *display) { if (display->eh.pres != PRSNT_NODEF) { return FTDM_FAIL; @@ -228,7 +228,7 @@ ftdm_status_t cpy_calling_name_from_sngisdn(ftdm_caller_data_t *ftdm, Display *d return FTDM_SUCCESS; } -ftdm_status_t cpy_calling_num_to_sngisdn(CgPtyNmb *cgPtyNmb, ftdm_caller_data_t *ftdm) +ftdm_status_t cpy_calling_num_from_user(CgPtyNmb *cgPtyNmb, ftdm_caller_data_t *ftdm) { uint8_t len = strlen(ftdm->cid_num.digits); if (!len) { @@ -256,7 +256,7 @@ ftdm_status_t cpy_calling_num_to_sngisdn(CgPtyNmb *cgPtyNmb, ftdm_caller_data_t return FTDM_SUCCESS; } -ftdm_status_t cpy_called_num_to_sngisdn(CdPtyNmb *cdPtyNmb, ftdm_caller_data_t *ftdm) +ftdm_status_t cpy_called_num_from_user(CdPtyNmb *cdPtyNmb, ftdm_caller_data_t *ftdm) { uint8_t len = strlen(ftdm->dnis.digits); if (!len) { @@ -286,7 +286,7 @@ ftdm_status_t cpy_called_num_to_sngisdn(CdPtyNmb *cdPtyNmb, ftdm_caller_data_t * return FTDM_SUCCESS; } -ftdm_status_t cpy_redir_num_to_sngisdn(RedirNmb *redirNmb, ftdm_caller_data_t *ftdm) +ftdm_status_t cpy_redir_num_from_user(RedirNmb *redirNmb, ftdm_caller_data_t *ftdm) { uint8_t len = strlen(ftdm->rdnis.digits); if (!len) { @@ -318,7 +318,7 @@ ftdm_status_t cpy_redir_num_to_sngisdn(RedirNmb *redirNmb, ftdm_caller_data_t *f } -ftdm_status_t cpy_calling_name_to_sngisdn(ConEvnt *conEvnt, ftdm_channel_t *ftdmchan) +ftdm_status_t cpy_calling_name_from_user(ConEvnt *conEvnt, ftdm_channel_t *ftdmchan) { uint8_t len; ftdm_caller_data_t *ftdm = &ftdmchan->caller_data; @@ -385,13 +385,7 @@ void sngisdn_delayed_release(void* p_sngisdn_info) signal_data->cc_id, sngisdn_info->glare.spInstId, sngisdn_info->glare.suInstId); sngisdn_snd_release(ftdmchan, 1); -#if 1 /* TODO: Confirm this */ clear_call_glare_data(sngisdn_info); -#else - g_sngisdn_data.ccs[signal_data->cc_id].active_spInstIds[sngisdn_info->glare.spInstId] = NULL; - g_sngisdn_data.ccs[signal_data->cc_id].active_suInstIds[sngisdn_info->glare.suInstId] = NULL; -#endif - } else { ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "Call was already released (suId:%d suInstId:%u spInstId:%u)\n", signal_data->cc_id, sngisdn_info->glare.spInstId, sngisdn_info->glare.suInstId); @@ -473,6 +467,72 @@ void get_memory_info(void) return; } +uint8_t sngisdn_get_infoTranCap_from_stack(ftdm_bearer_cap_t bearer_capability) +{ + switch(bearer_capability) { + case FTDM_BEARER_CAP_SPEECH: + return IN_ITC_SPEECH; + + case FTDM_BEARER_CAP_64K_UNRESTRICTED: + return IN_ITC_UNRDIG; + + case FTDM_BEARER_CAP_3_1KHZ_AUDIO: + return IN_ITC_A31KHZ; + + /* Do not put a default case here, so we can see compile warnings if we have unhandled cases */ + } + return FTDM_BEARER_CAP_SPEECH; +} + +uint8_t sngisdn_get_usrInfoLyr1Prot_from_stack(ftdm_user_layer1_prot_t layer1_prot) +{ + switch(layer1_prot) { + case FTDM_USER_LAYER1_PROT_V110: + return IN_UIL1_CCITTV110; + + case FTDM_USER_LAYER1_PROT_ULAW: + return IN_UIL1_G711ULAW; + + case FTDM_USER_LAYER1_PROT_ALAW: + return IN_UIL1_G711ALAW; + + /* Do not put a default case here, so we can see compile warnings if we have unhandled cases */ + } + return IN_UIL1_G711ULAW; +} + +ftdm_bearer_cap_t sngisdn_get_infoTranCap_from_user(uint8_t bearer_capability) +{ + switch(bearer_capability) { + case IN_ITC_SPEECH: + return FTDM_BEARER_CAP_SPEECH; + + case IN_ITC_UNRDIG: + return FTDM_BEARER_CAP_64K_UNRESTRICTED; + + case IN_ITC_A31KHZ: + return FTDM_BEARER_CAP_3_1KHZ_AUDIO; + + default: + return FTDM_BEARER_CAP_SPEECH; + } + return FTDM_BEARER_CAP_SPEECH; +} + +ftdm_user_layer1_prot_t sngisdn_get_usrInfoLyr1Prot_from_user(uint8_t layer1_prot) +{ + switch(layer1_prot) { + case IN_UIL1_CCITTV110: + return FTDM_USER_LAYER1_PROT_V110; + case IN_UIL1_G711ULAW: + return FTDM_USER_LAYER1_PROT_ULAW; + case IN_UIL1_G711ALAW: + return IN_UIL1_G711ALAW; + default: + return FTDM_USER_LAYER1_PROT_ULAW; + } + return FTDM_USER_LAYER1_PROT_ULAW; +} /* For Emacs: * Local Variables: diff --git a/libs/freetdm/src/include/freetdm.h b/libs/freetdm/src/include/freetdm.h index c1e50ecb67..205833d3f8 100644 --- a/libs/freetdm/src/include/freetdm.h +++ b/libs/freetdm/src/include/freetdm.h @@ -60,6 +60,8 @@ /*! \brief Max number of groups */ #define FTDM_MAX_GROUPS_INTERFACE FTDM_MAX_SPANS_INTERFACE +#define FTDM_INVALID_INT_PARM 0xFF + /*! \brief FreeTDM APIs possible return codes */ typedef enum { FTDM_SUCCESS, /*!< Success */ @@ -208,6 +210,7 @@ typedef struct ftdm_queue_handler { ftdm_queue_destroy_func_t destroy; } ftdm_queue_handler_t; + /*! \brief Type Of Number (TON) */ typedef enum { FTDM_TON_UNKNOWN = 0, diff --git a/libs/freetdm/src/include/private/ftdm_call_utils.h b/libs/freetdm/src/include/private/ftdm_call_utils.h index 57f2f4b133..782abde927 100644 --- a/libs/freetdm/src/include/private/ftdm_call_utils.h +++ b/libs/freetdm/src/include/private/ftdm_call_utils.h @@ -39,6 +39,8 @@ FT_DECLARE(ftdm_status_t) ftdm_span_set_npi(const char *npi_string, uint8_t *target); FT_DECLARE(ftdm_status_t) ftdm_span_set_ton(const char *ton_string, uint8_t *target); +FT_DECLARE(ftdm_status_t) ftdm_span_set_bearer_capability(const char *bc_string, ftdm_bearer_cap_t *target); +FT_DECLARE(ftdm_status_t) ftdm_span_set_bearer_layer1(const char *bc_string, ftdm_user_layer1_prot_t *target); FT_DECLARE(ftdm_status_t) ftdm_is_number(char *number); #endif /* __FTDM_CALL_UTILS_H__ */ From abb342f4305fd2eca9f92b046400a513664f7b68 Mon Sep 17 00:00:00 2001 From: David Yat Sin Date: Wed, 1 Sep 2010 16:35:59 -0400 Subject: [PATCH 08/10] Initialized bearer_cap to FTDM_INVALID_INT_PARM --- libs/freetdm/mod_freetdm/mod_freetdm.c | 10 +++------- .../ftmod_sangoma_isdn_stack_rcv.c | 18 ++++++++++-------- 2 files changed, 13 insertions(+), 15 deletions(-) diff --git a/libs/freetdm/mod_freetdm/mod_freetdm.c b/libs/freetdm/mod_freetdm/mod_freetdm.c index 0d986f35a6..8b4dd68f5b 100755 --- a/libs/freetdm/mod_freetdm/mod_freetdm.c +++ b/libs/freetdm/mod_freetdm/mod_freetdm.c @@ -1230,14 +1230,10 @@ static switch_call_cause_t channel_outgoing_channel(switch_core_session_t *sessi freetdmvar = switch_channel_get_variable(channel, "freetdm_bearer_capability"); if (freetdmvar) { caller_data.bearer_capability = (uint8_t)atoi(freetdmvar); - } else { - caller_data.bearer_capability = FTDM_INVALID_INT_PARM; } freetdmvar = switch_channel_get_variable(channel, "freetdm_bearer_layer1"); if (freetdmvar) { caller_data.bearer_layer1 = (uint8_t)atoi(freetdmvar); - } else { - caller_data.bearer_layer1 = FTDM_INVALID_INT_PARM; } } @@ -3407,9 +3403,9 @@ static switch_status_t load_config(void) boost_span = boost_spans[i]; ftdm_log(FTDM_LOG_DEBUG, "Starting boost span %d\n", ftdm_span_get_id(boost_span)); if (ftdm_span_start(boost_span) == FTDM_FAIL) { - ftdm_log(FTDM_LOG_ERROR, "Error starting boost FreeTDM span %d, error: %s\n", - ftdm_span_get_id(boost_span), ftdm_span_get_last_error(boost_span)); - continue; + ftdm_log(FTDM_LOG_ERROR, "Error starting boost FreeTDM span %d, error: %s\n", + ftdm_span_get_id(boost_span), ftdm_span_get_last_error(boost_span)); + continue; } } diff --git a/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_stack_rcv.c b/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_stack_rcv.c index 1c49674eeb..75513fb0a0 100644 --- a/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_stack_rcv.c +++ b/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_stack_rcv.c @@ -187,6 +187,7 @@ void sngisdn_rcv_disc_ind (int16_t suId, uint32_t suInstId, uint32_t spInstId, D !(suInstId && get_ftdmchan_by_suInstId(suId, suInstId, &sngisdn_info) == FTDM_SUCCESS)) { ftdm_log(FTDM_LOG_CRIT, "Could not find matching call suId:%u suInstId:%u spInstId:%u\n", suId, suInstId, spInstId); + ftdm_assert(0, "Inconsistent call states\n"); return; } @@ -219,6 +220,7 @@ void sngisdn_rcv_rel_ind (int16_t suId, uint32_t suInstId, uint32_t spInstId, Re !(suInstId && get_ftdmchan_by_suInstId(suId, suInstId, &sngisdn_info) == FTDM_SUCCESS)) { ftdm_log(FTDM_LOG_CRIT, "Could not find matching call suId:%u suInstId:%u spInstId:%u\n", suId, suInstId, spInstId); + ftdm_assert(0, "Inconsistent call states\n"); return; } @@ -250,7 +252,7 @@ void sngisdn_rcv_dat_ind (int16_t suId, uint32_t suInstId, uint32_t spInstId, In !(suInstId && get_ftdmchan_by_suInstId(suId, suInstId, &sngisdn_info) == FTDM_SUCCESS)) { ftdm_log(FTDM_LOG_CRIT, "Could not find matching call suId:%u suInstId:%u spInstId:%u\n", suId, suInstId, spInstId); - + ftdm_assert(0, "Inconsistent call states\n"); return; } @@ -282,7 +284,7 @@ void sngisdn_rcv_sshl_ind (int16_t suId, uint32_t suInstId, uint32_t spInstId, S !(suInstId && get_ftdmchan_by_suInstId(suId, suInstId, &sngisdn_info) == FTDM_SUCCESS)) { ftdm_log(FTDM_LOG_CRIT, "Could not find matching call suId:%u suInstId:%u spInstId:%u\n", suId, suInstId, spInstId); - + ftdm_assert(0, "Inconsistent call states\n"); return; } @@ -315,7 +317,7 @@ void sngisdn_rcv_sshl_cfm (int16_t suId, uint32_t suInstId, uint32_t spInstId, S !(suInstId && get_ftdmchan_by_suInstId(suId, suInstId, &sngisdn_info) == FTDM_SUCCESS)) { ftdm_log(FTDM_LOG_CRIT, "Could not find matching call suId:%u suInstId:%u spInstId:%u\n", suId, suInstId, spInstId); - + ftdm_assert(0, "Inconsistent call states\n"); return; } @@ -347,7 +349,7 @@ void sngisdn_rcv_rmrt_ind (int16_t suId, uint32_t suInstId, uint32_t spInstId, R !(suInstId && get_ftdmchan_by_suInstId(suId, suInstId, &sngisdn_info) == FTDM_SUCCESS)) { ftdm_log(FTDM_LOG_CRIT, "Could not find matching call suId:%u suInstId:%u spInstId:%u\n", suId, suInstId, spInstId); - + ftdm_assert(0, "Inconsistent call states\n"); return; } @@ -380,7 +382,7 @@ void sngisdn_rcv_rmrt_cfm (int16_t suId, uint32_t suInstId, uint32_t spInstId, R !(suInstId && get_ftdmchan_by_suInstId(suId, suInstId, &sngisdn_info) == FTDM_SUCCESS)) { ftdm_log(FTDM_LOG_CRIT, "Could not find matching call suId:%u suInstId:%u spInstId:%u\n", suId, suInstId, spInstId); - + ftdm_assert(0, "Inconsistent call states\n"); return; } @@ -413,7 +415,7 @@ void sngisdn_rcv_flc_ind (int16_t suId, uint32_t suInstId, uint32_t spInstId, St !(suInstId && get_ftdmchan_by_suInstId(suId, suInstId, &sngisdn_info) == FTDM_SUCCESS)) { ftdm_log(FTDM_LOG_CRIT, "Could not find matching call suId:%u suInstId:%u spInstId:%u\n", suId, suInstId, spInstId); - + ftdm_assert(0, "Inconsistent call states\n"); return; } @@ -446,7 +448,7 @@ void sngisdn_rcv_fac_ind (int16_t suId, uint32_t suInstId, uint32_t spInstId, Fa !(suInstId && get_ftdmchan_by_suInstId(suId, suInstId, &sngisdn_info) == FTDM_SUCCESS)) { ftdm_log(FTDM_LOG_CRIT, "Could not find matching call suId:%u suInstId:%u spInstId:%u\n", suId, suInstId, spInstId); - + ftdm_assert(0, "Inconsistent call states\n"); return; } @@ -479,7 +481,7 @@ void sngisdn_rcv_sta_cfm (int16_t suId, uint32_t suInstId, uint32_t spInstId, St !(suInstId && get_ftdmchan_by_suInstId(suId, suInstId, &sngisdn_info) == FTDM_SUCCESS)) { ftdm_log(FTDM_LOG_CRIT, "Could not find matching call suId:%u suInstId:%u spInstId:%u\n", suId, suInstId, spInstId); - + ftdm_assert(0, "Inconsistent call states\n"); return; } From 71fd30d40e5d0c87575a4e95cce1890950bdbc3d Mon Sep 17 00:00:00 2001 From: David Yat Sin Date: Fri, 3 Sep 2010 15:27:42 -0400 Subject: [PATCH 09/10] spInstId's are now saved before queueing the SETUP event --- .../ftmod_sangoma_isdn_stack_hndl.c | 46 ++----------------- .../ftmod_sangoma_isdn_stack_out.c | 2 +- .../ftmod_sangoma_isdn_stack_rcv.c | 33 +++++++++++-- 3 files changed, 36 insertions(+), 45 deletions(-) diff --git a/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_stack_hndl.c b/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_stack_hndl.c index f49d651c09..c3d97e5c5c 100644 --- a/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_stack_hndl.c +++ b/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_stack_hndl.c @@ -78,7 +78,7 @@ void sngisdn_process_con_ind (sngisdn_event_data_t *sngisdn_event) } sngisdn_info->suInstId = get_unique_suInstId(suId); - sngisdn_info->spInstId = spInstId; + sngisdn_info->spInstId = spInstId; /* If this is a glared call that was previously saved, we moved all the info to the current call, so clear the glared saved data */ @@ -87,10 +87,7 @@ void sngisdn_process_con_ind (sngisdn_event_data_t *sngisdn_event) clear_call_glare_data(sngisdn_info); } - ftdm_assert(g_sngisdn_data.ccs[suId].active_spInstIds[spInstId] == NULL, "Con Ind on busy spInstId"); - ftdm_mutex_lock(g_sngisdn_data.ccs[suId].mutex); - g_sngisdn_data.ccs[suId].active_spInstIds[spInstId] = sngisdn_info; g_sngisdn_data.ccs[suId].active_suInstIds[sngisdn_info->suInstId] = sngisdn_info; ftdm_mutex_unlock(g_sngisdn_data.ccs[suId].mutex); @@ -118,7 +115,7 @@ void sngisdn_process_con_ind (sngisdn_event_data_t *sngisdn_event) ftdmchan->caller_data.bearer_layer1 = sngisdn_get_infoTranCap_from_stack(conEvnt->bearCap[0].usrInfoLyr1Prot.val); ftdmchan->caller_data.bearer_capability = sngisdn_get_infoTranCap_from_stack(conEvnt->bearCap[0].infoTranCap.val); } - + if (signal_data->switchtype == SNGISDN_SWITCH_NI2) { if (conEvnt->shift11.eh.pres && conEvnt->ni2OctStr.eh.pres) { if (conEvnt->ni2OctStr.str.len == 4 && conEvnt->ni2OctStr.str.val[0] == 0x37) { @@ -160,7 +157,7 @@ void sngisdn_process_con_ind (sngisdn_event_data_t *sngisdn_event) break; case FTDM_CHANNEL_STATE_TERMINATING: ftdm_log_chan_msg(ftdmchan, FTDM_LOG_INFO, "Processing SETUP in TERMINATING state, saving SETUP info for later processing\n"); - ftdm_assert(!sngisdn_test_flag(sngisdn_info, FLAG_GLARE), "Trying to save GLARE info, but we already had a glare"); + ftdm_assert(!sngisdn_test_flag(sngisdn_info, FLAG_GLARE), "Trying to save GLARE info, but we already had a glare\n"); sngisdn_set_flag(sngisdn_info, FLAG_GLARE); @@ -172,11 +169,6 @@ void sngisdn_process_con_ind (sngisdn_event_data_t *sngisdn_event) sngisdn_info->glare.dChan = dChan; sngisdn_info->glare.ces = ces; - /* We need to register the spInstId in case we get a release for that call while it is still stored in sngisdn_info->glare */ - ftdm_mutex_lock(g_sngisdn_data.ccs[suId].mutex); - g_sngisdn_data.ccs[suId].active_spInstIds[spInstId] = sngisdn_info; - ftdm_mutex_unlock(g_sngisdn_data.ccs[suId].mutex); - break; case FTDM_CHANNEL_STATE_DIALING: /* glare */ if (signal_data->signalling == SNGISDN_SIGNALING_NET) { @@ -188,11 +180,6 @@ void sngisdn_process_con_ind (sngisdn_event_data_t *sngisdn_event) sngisdn_info->glare.suInstId = get_unique_suInstId(suId); sngisdn_info->glare.spInstId = spInstId; - ftdm_mutex_lock(g_sngisdn_data.ccs[suId].mutex); - g_sngisdn_data.ccs[suId].active_spInstIds[spInstId] = sngisdn_info; - g_sngisdn_data.ccs[suId].active_suInstIds[sngisdn_info->suInstId] = sngisdn_info; - ftdm_mutex_unlock(g_sngisdn_data.ccs[suId].mutex); - sngisdn_info->glare.dChan = dChan; sngisdn_info->glare.ces = ces; ftdmchan->caller_data.hangup_cause = 0x2C; /* Channel requested not available */ @@ -212,10 +199,6 @@ void sngisdn_process_con_ind (sngisdn_event_data_t *sngisdn_event) sngisdn_info->glare.dChan = dChan; sngisdn_info->glare.ces = ces; - /* We need to register the spInstId in case we get a release for that call while it is still stored in sngisdn_info->glare */ - ftdm_mutex_lock(g_sngisdn_data.ccs[suId].mutex); - g_sngisdn_data.ccs[suId].active_spInstIds[spInstId] = sngisdn_info; - ftdm_mutex_unlock(g_sngisdn_data.ccs[suId].mutex); ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_TERMINATING); } break; @@ -245,13 +228,6 @@ void sngisdn_process_con_cfm (sngisdn_event_data_t *sngisdn_event) ftdm_assert(!ftdm_test_flag(ftdmchan, FTDM_CHANNEL_STATE_CHANGE), "State change flag pending\n"); ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "Processing CONNECT/CONNECT ACK (suId:%u suInstId:%u spInstId:%u ces:%d)\n", suId, suInstId, spInstId, ces); - - if (!sngisdn_info->spInstId) { - ftdm_mutex_lock(g_sngisdn_data.ccs[suId].mutex); - sngisdn_info->spInstId = spInstId; - g_sngisdn_data.ccs[suId].active_spInstIds[spInstId] = sngisdn_info; - ftdm_mutex_unlock(g_sngisdn_data.ccs[suId].mutex); - } if (ftdmchan->span->trunk_type == FTDM_TRUNK_BRI_PTMP && ((sngisdn_span_data_t*)ftdmchan->span->signal_data)->signalling == SNGISDN_SIGNALING_NET) { @@ -315,13 +291,6 @@ void sngisdn_process_cnst_ind (sngisdn_event_data_t *sngisdn_event) CnStEvnt *cnStEvnt = &sngisdn_event->event.cnStEvnt; - if (!sngisdn_info->spInstId) { - ftdm_mutex_lock(g_sngisdn_data.ccs[suId].mutex); - sngisdn_info->spInstId = spInstId; - g_sngisdn_data.ccs[suId].active_spInstIds[spInstId] = sngisdn_info; - ftdm_mutex_unlock(g_sngisdn_data.ccs[suId].mutex); - } - ftdm_assert(!ftdm_test_flag(ftdmchan, FTDM_CHANNEL_STATE_CHANGE), "State change flag pending\n"); ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "Processing %s (suId:%u suInstId:%u spInstId:%u ces:%d)\n", @@ -418,13 +387,6 @@ void sngisdn_process_disc_ind (sngisdn_event_data_t *sngisdn_event) DiscEvnt *discEvnt = &sngisdn_event->event.discEvnt; - if (!sngisdn_info->spInstId) { - ftdm_mutex_lock(g_sngisdn_data.ccs[suId].mutex); - sngisdn_info->spInstId = spInstId; - g_sngisdn_data.ccs[suId].active_spInstIds[spInstId] = sngisdn_info; - ftdm_mutex_unlock(g_sngisdn_data.ccs[suId].mutex); - } - ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "Processing DISCONNECT (suId:%u suInstId:%u spInstId:%u)\n", suId, suInstId, spInstId); ftdm_assert(!ftdm_test_flag(ftdmchan, FTDM_CHANNEL_STATE_CHANGE), "State change flag pending\n"); @@ -698,6 +660,7 @@ void sngisdn_process_fac_ind (sngisdn_event_data_t *sngisdn_event) ftdm_log_chan_msg(ftdmchan, FTDM_LOG_WARNING, "Failed to retrieve Caller Name from Facility IE\n"); } } + ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_RING); break; default: @@ -876,6 +839,7 @@ void sngisdn_process_sta_cfm (sngisdn_event_data_t *sngisdn_event) case 9: switch (ftdmchan->state) { case FTDM_CHANNEL_STATE_PROGRESS: + case FTDM_CHANNEL_STATE_PROGRESS_MEDIA: /* Do nothing */ break; default: diff --git a/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_stack_out.c b/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_stack_out.c index 8ae513881b..6e8e0e81fd 100644 --- a/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_stack_out.c +++ b/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_stack_out.c @@ -283,7 +283,7 @@ void sngisdn_snd_proceed(ftdm_channel_t *ftdmchan) sngisdn_chan_data_t *sngisdn_info = (sngisdn_chan_data_t*) ftdmchan->call_data; sngisdn_span_data_t *signal_data = (sngisdn_span_data_t*) ftdmchan->span->signal_data; - if (!sngisdn_info->suInstId || !sngisdn_info->spInstId) { + if (!sngisdn_info->suInstId || !sngisdn_info->spInstId) { ftdm_log_chan(ftdmchan, FTDM_LOG_ERROR, "Sending PROGRESS, but no call data, aborting (suId:%d suInstId:%u spInstId:%u)\n", signal_data->cc_id, sngisdn_info->suInstId, sngisdn_info->spInstId); sngisdn_set_flag(sngisdn_info, FLAG_LOCAL_ABORT); ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_TERMINATING); diff --git a/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_stack_rcv.c b/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_stack_rcv.c index 75513fb0a0..29cfb2330e 100644 --- a/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_stack_rcv.c +++ b/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_stack_rcv.c @@ -87,11 +87,14 @@ void sngisdn_rcv_con_ind (int16_t suId, uint32_t suInstId, uint32_t spInstId, Co sngisdn_event->event_id = SNGISDN_EVENT_CON_IND; sngisdn_event->sngisdn_info = sngisdn_info; sngisdn_event->suId = suId; - sngisdn_event->suInstId = suInstId; sngisdn_event->spInstId = spInstId; sngisdn_event->dChan = dChan; sngisdn_event->ces = ces; + ftdm_mutex_lock(g_sngisdn_data.ccs[suId].mutex); + g_sngisdn_data.ccs[suId].active_spInstIds[spInstId] = sngisdn_info; + ftdm_mutex_unlock(g_sngisdn_data.ccs[suId].mutex); + memcpy(&sngisdn_event->event.conEvnt, conEvnt, sizeof(*conEvnt)); ftdm_queue_enqueue(((sngisdn_span_data_t*)sngisdn_info->ftdmchan->span->signal_data)->event_queue, sngisdn_event); @@ -113,6 +116,14 @@ void sngisdn_rcv_con_cfm (int16_t suId, uint32_t suInstId, uint32_t spInstId, Cn return; } + if (!sngisdn_info->spInstId) { + ftdm_mutex_lock(g_sngisdn_data.ccs[suId].mutex); + sngisdn_info->spInstId = spInstId; + g_sngisdn_data.ccs[suId].active_spInstIds[spInstId] = sngisdn_info; + ftdm_mutex_unlock(g_sngisdn_data.ccs[suId].mutex); + } + + ftdm_log_chan(sngisdn_info->ftdmchan, FTDM_LOG_INFO, "Received CONNECT/CONNECT ACK (suId:%u suInstId:%u spInstId:%u ces:%d)\n", suId, suInstId, spInstId, ces); sngisdn_event = ftdm_malloc(sizeof(*sngisdn_event)); @@ -126,7 +137,6 @@ void sngisdn_rcv_con_cfm (int16_t suId, uint32_t suInstId, uint32_t spInstId, Cn sngisdn_event->spInstId = spInstId; sngisdn_event->dChan = dChan; sngisdn_event->ces = ces; - memcpy(&sngisdn_event->event.cnStEvnt, cnStEvnt, sizeof(*cnStEvnt)); ftdm_queue_enqueue(((sngisdn_span_data_t*)sngisdn_info->ftdmchan->span->signal_data)->event_queue, sngisdn_event); @@ -148,6 +158,13 @@ void sngisdn_rcv_cnst_ind (int16_t suId, uint32_t suInstId, uint32_t spInstId, C return; } + if (!sngisdn_info->spInstId) { + ftdm_mutex_lock(g_sngisdn_data.ccs[suId].mutex); + sngisdn_info->spInstId = spInstId; + g_sngisdn_data.ccs[suId].active_spInstIds[spInstId] = sngisdn_info; + ftdm_mutex_unlock(g_sngisdn_data.ccs[suId].mutex); + } + ftdm_log_chan(sngisdn_info->ftdmchan, FTDM_LOG_INFO, "Received %s (suId:%u suInstId:%u spInstId:%u ces:%d)\n", (evntType == MI_ALERTING)?"ALERT": (evntType == MI_CALLPROC)?"PROCEED": @@ -191,6 +208,13 @@ void sngisdn_rcv_disc_ind (int16_t suId, uint32_t suInstId, uint32_t spInstId, D return; } + if (!sngisdn_info->spInstId) { + ftdm_mutex_lock(g_sngisdn_data.ccs[suId].mutex); + sngisdn_info->spInstId = spInstId; + g_sngisdn_data.ccs[suId].active_spInstIds[spInstId] = sngisdn_info; + ftdm_mutex_unlock(g_sngisdn_data.ccs[suId].mutex); + } + ftdm_log_chan(sngisdn_info->ftdmchan, FTDM_LOG_INFO, "Received DISCONNECT (suId:%u suInstId:%u spInstId:%u)\n", suId, suInstId, spInstId); sngisdn_event = ftdm_malloc(sizeof(*sngisdn_event)); @@ -643,7 +667,10 @@ void sngisdn_rcv_q921_ind(BdMngmt *status) } } } - ftdm_assert(ftdmspan != NULL, "Received q921 status on unconfigured span\n"); + if (ftdmspan == NULL) { + ftdm_log(FTDM_LOG_WARNING, "Received q921 status on unconfigured span (lnkNmb:%d)\n", status->t.usta.lnkNmb); + return; + } switch (status->t.usta.alarm.category) { case (LCM_CATEGORY_INTERFACE): From 2f01722ebadcb049c1080c545073fed226a3af3e Mon Sep 17 00:00:00 2001 From: David Yat Sin Date: Fri, 3 Sep 2010 17:09:21 -0400 Subject: [PATCH 10/10] fixed tabs --- .../freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn.c b/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn.c index ef440634c8..9ffd7097a3 100644 --- a/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn.c +++ b/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn.c @@ -281,8 +281,8 @@ static void *ftdm_sangoma_isdn_run(ftdm_thread_t *me, void *obj) while ((sngisdn_event = ftdm_queue_dequeue(signal_data->event_queue))) { ftdm_sangoma_isdn_process_stack_event(span, sngisdn_event); ftdm_safe_free(sngisdn_event); - } - ftdm_span_trigger_signals(span); + } + ftdm_span_trigger_signals(span); break; case FTDM_TIMEOUT: /* twiddle */