]> git.ipfire.org Git - thirdparty/freeswitch.git/commitdiff
chlog: freetdm - SS7: Support for Transparent IAM
authorDavid Yat Sin <dyatsin@sangoma.com>
Tue, 17 May 2011 21:13:38 +0000 (17:13 -0400)
committerDavid Yat Sin <dyatsin@sangoma.com>
Tue, 17 May 2011 21:27:05 +0000 (17:27 -0400)
13 files changed:
libs/freetdm/configure.ac
libs/freetdm/mod_freetdm/mod_freetdm.c
libs/freetdm/src/ftdm_call_utils.c
libs/freetdm/src/ftdm_io.c
libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_support.c
libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_handle.c
libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_main.c
libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_main.h
libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_out.c
libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_support.c
libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_xml.c
libs/freetdm/src/include/freetdm.h
libs/freetdm/src/include/ftdm_call_utils.h

index 55185cb10dfbc6f3e69a04cabeaa143a67e0148f..493f0da3b0c882d707b9710fe7855d86e3ee5c29 100644 (file)
@@ -294,6 +294,19 @@ if test "${HAVE_SNG_SS7}" = "yes"; then
        fi
 fi
 
+
+##
+# zlib (required for Sangoma SS7 Transparent IAM)
+#
+HAVE_ZLIB="no"
+AC_MSG_RESULT([${as_nl}<<>> zlib])
+AC_CHECK_LIB([z], [compress], [HAVE_ZLIB="yes"])
+AC_MSG_RESULT([checking whether zlib is installed... ${HAVE_ZLIB}])
+AM_CONDITIONAL([HAVE_ZLIB], [test "{HAVE_ZLIB]" = "yes"])
+if test "${HAVE_ZLIB}" = "yes"; then
+       CFLAGS="$CFLAGS -DHAVE_ZLIB"
+fi
+
 ##
 # libisdn
 #
index 954a568e6fcbe9aef1b116b31fc031e8daa2f46e..75b500d0f6ce1eb1b044adcea9e92984847d4b9f 100755 (executable)
@@ -1369,7 +1369,12 @@ static switch_call_cause_t channel_outgoing_channel(switch_core_session_t *sessi
 
                sipvar = switch_channel_get_variable(channel, "sip_h_X-FreeTDM-CPC");
                if (sipvar) {
-                       ftdm_set_calling_party_category(var, (uint8_t *)&caller_data.cpc);
+                       ftdm_set_calling_party_category(sipvar, (uint8_t *)&caller_data.cpc);
+               }
+               
+               sipvar = switch_channel_get_variable(channel, "sip_h_X-FreeTDM-IAM");
+               if (sipvar) {
+                       ftdm_usrmsg_add_var(&usrmsg, "ss7_iam", sipvar);
                }
        }
 
@@ -1443,7 +1448,13 @@ static switch_call_cause_t channel_outgoing_channel(switch_core_session_t *sessi
                if (!strncasecmp(h->name, FREETDM_VAR_PREFIX, FREETDM_VAR_PREFIX_LEN)) {
                        char *v = h->name + FREETDM_VAR_PREFIX_LEN;
                        if (!zstr(v)) {
-                               switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Adding outbound freetdm variable %s=%s to channel %d:%d\n", v, h->value, span_id, chan_id);
+                               if (!strcasecmp(v, "ss7_iam")) {
+                                       /* Do not print the value of ss7_iam as it is very long */
+                                       switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Adding outbound freetdm variable %s to channel %d:%d\n", v, span_id, chan_id);
+                               } else {
+                                       switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Adding outbound freetdm variable %s=%s to channel %d:%d\n", v, h->value, span_id, chan_id);
+                               }
+                               
                                ftdm_usrmsg_add_var(&usrmsg, v, h->value);
                        }
                }
@@ -1633,6 +1644,8 @@ ftdm_status_t ftdm_channel_from_event(ftdm_sigmsg_t *sigmsg, switch_core_session
                switch_channel_set_variable_printf(channel, "sip_h_X-FreeTDM-RDNIS", "%s", channel_caller_data->rdnis.digits);
                switch_channel_set_variable_printf(channel, "sip_h_X-FreeTDM-RDNIS-NADI", "%d", channel_caller_data->rdnis.type);
                switch_channel_set_variable_printf(channel, "sip_h_X-FreeTDM-RDNIS-Plan", "%d", channel_caller_data->rdnis.plan);
+               switch_channel_set_variable_printf(channel, "sip_h_X-FreeTDM-CPC", "%s", ftdm_calling_party_category2str(channel_caller_data->cpc));
+               
 
                var_value = ftdm_sigmsg_get_var(sigmsg, "ss7_rdnis_screen_ind");
                if (!ftdm_strlen_zero(var_value)) {
@@ -1678,10 +1691,10 @@ ftdm_status_t ftdm_channel_from_event(ftdm_sigmsg_t *sigmsg, switch_core_session
                                switch_channel_set_variable_printf(channel, "sip_h_X-FreeTDM-GN-NumInComp", "%d", var_value);
                        }
                } /* End - var_value = ftdm_sigmsg_get_var(sigmsg, "ss7_gn_digits"); */
-               
-               var_value = ftdm_sigmsg_get_var(sigmsg, "freetdm_calling_party_category");
+
+               var_value = ftdm_sigmsg_get_var(sigmsg, "ss7_iam");
                if (!ftdm_strlen_zero(var_value)) {
-                       switch_channel_set_variable_printf(channel, "sip_h_X-FreeTDM-CPC", "%s", var_value);
+                       switch_channel_set_variable_printf(channel, "sip_h_X-FreeTDM-IAM", "%s", var_value);
                }
 
                switch_channel_set_variable_printf(channel, "sip_h_X-FreeTDM-Screen", "%d", channel_caller_data->screen);
@@ -1694,7 +1707,12 @@ ftdm_status_t ftdm_channel_from_event(ftdm_sigmsg_t *sigmsg, switch_core_session
                ftdm_get_current_var(curr, &var_name, &var_value);
                snprintf(name, sizeof(name), FREETDM_VAR_PREFIX "%s", var_name);
                switch_channel_set_variable_printf(channel, name, "%s", var_value);
-               switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Call Variable: %s = %s\n", name, var_value);
+               if (!strcasecmp(var_name, "ss7_iam")) {
+                       /* Do not print freetdm_ss7_iam as it is a very long variable */
+                       switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Call Variable: %s is present\n", name);
+               } else {
+                       switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Call Variable: %s = %s\n", name, var_value);
+               }
        }
        ftdm_iterator_free(iter);
        
index 2b72f05b77e1aaf6f42f69c12c8ead7979aea3c8..d23c95af4e7473b2807541465f4b533be44668ce 100644 (file)
 #include <ctype.h>
 
 
+
+
+FT_DECLARE(char *) ftdm_url_encode(const char *url, char *buf, ftdm_size_t len)
+{
+       /* This implementation of url_encode is slightly different compared to the
+       * Freeswitch one. This is because this implementation accepts the full
+       * range of values (0x00 - 0xFF) compared to the Freeswitch implementation
+       * that does not accept 0x00 */
+
+       const char *p;
+       size_t x = 0,y = 0;
+       const char urlunsafe[] = "\r\n \"#%&+:;<=>?@[\\]^`{|}";
+       const char hex[] = "0123456789ABCDEF";
+
+       if (!buf) {
+               return 0;
+       }
+
+       if (!url) {
+               return 0;
+       }
+
+       len--;
+
+       for (p = url; y <= len; p++) {          
+               if (*p < ' ' || *p > '~' || strchr(urlunsafe, *p)) {
+                       buf[x++] = '%';
+                       buf[x++] = hex[(*p >> 4) & 0x0f];
+                       buf[x++] = hex[*p & 0x0f];
+               } else {
+                       buf[x++] = *p;
+               }
+               y++;
+       }
+       buf[x] = '\0';
+       return buf;
+}
+
+
+FT_DECLARE(char *) ftdm_url_decode(char *s, ftdm_size_t *len)
+{
+       /* This implementation of url_decode is slightly different compared to the
+       * Freeswitch one. This is because this implementation accepts the full
+       * range of values (0x00 - 0xFF) compared to the Freeswitch implementation
+       * that does not accept 0x00 */
+       
+       char *o;
+       unsigned int tmp;
+       ftdm_size_t mylen = 0;
+
+       if (ftdm_strlen_zero(s)) {
+               return s;
+       }
+       
+       for (o = s; *s; s++, o++) {
+               if (*s == '%' && strlen(s) > 2 && sscanf(s + 1, "%2x", &tmp) == 1) {
+                       *o = (char) tmp;
+                       s += 2;
+               } else {
+                       *o = *s;
+               }
+               mylen++;
+       }
+       *o = '\0';
+       *len = mylen;
+       return s;
+}
+
 FT_DECLARE(ftdm_status_t) ftdm_set_npi(const char *string, uint8_t *target)
 {
        uint8_t val;
index 1d7a0d1eb1764eed533e15910c5e649b9fd9ab17..c7a3ec48f4b12c3acc5e8ba1e4c9c1c8f9965ab7 100644 (file)
@@ -411,13 +411,13 @@ FT_DECLARE(void) ftdm_set_echocancel_call_begin(ftdm_channel_t *chan)
        if (ftdm_channel_test_feature(chan, FTDM_CHANNEL_FEATURE_HWEC)) {
                if (ftdm_channel_test_feature(chan, FTDM_CHANNEL_FEATURE_HWEC_DISABLED_ON_IDLE)) {
                        /* If the ec is disabled on idle, we need to enable it unless is a digital call */
-                       if (caller_data->bearer_capability != FTDM_BEARER_CAP_64K_UNRESTRICTED) {
+                       if (caller_data->bearer_capability != FTDM_BEARER_CAP_UNRESTRICTED) {
                                ftdm_log_chan(chan, FTDM_LOG_DEBUG, "Enabling ec for call in channel state %s\n", ftdm_channel_state2str(chan->state));
                                ftdm_channel_command(chan, FTDM_COMMAND_ENABLE_ECHOCANCEL, NULL);
                        }
                } else {
                        /* If the ec is enabled on idle, we do nothing unless is a digital call that needs it disabled */
-                       if (caller_data->bearer_capability == FTDM_BEARER_CAP_64K_UNRESTRICTED) {
+                       if (caller_data->bearer_capability == FTDM_BEARER_CAP_UNRESTRICTED) {
                                ftdm_log_chan(chan, FTDM_LOG_DEBUG, "Disabling ec for digital call in channel state %s\n", ftdm_channel_state2str(chan->state));
                                ftdm_channel_command(chan, FTDM_COMMAND_DISABLE_ECHOCANCEL, NULL);
                        }
index a343809b4c5dcce1507ae4f84cad899422f7ab3c..f4fee712c92cc3319c1ef0e5d87d64465c839244 100644 (file)
@@ -1069,18 +1069,20 @@ void get_memory_info(void)
        return;
 }
 
+
 uint8_t sngisdn_get_infoTranCap_from_user(ftdm_bearer_cap_t bearer_capability)
 {
        switch(bearer_capability) {
        case FTDM_BEARER_CAP_SPEECH:
                return IN_ITC_SPEECH;
-       case FTDM_BEARER_CAP_64K_UNRESTRICTED:
+       case FTDM_BEARER_CAP_UNRESTRICTED:
                return IN_ITC_UNRDIG;
        case FTDM_BEARER_CAP_3_1KHZ_AUDIO:
                return IN_ITC_A31KHZ;
        case FTDM_BEARER_CAP_INVALID:
                return IN_ITC_SPEECH;
-               /* Do not put a default case here, so we can see compile warnings if we have unhandled cases */
+       default:
+               return IN_ITC_SPEECH;
        }
        return FTDM_BEARER_CAP_SPEECH;
 }
@@ -1096,7 +1098,8 @@ uint8_t sngisdn_get_usrInfoLyr1Prot_from_user(ftdm_user_layer1_prot_t layer1_pro
                return IN_UIL1_G711ALAW;
        case FTDM_USER_LAYER1_PROT_INVALID:
                return IN_UIL1_G711ULAW;
-       /* Do not put a default case here, so we can see compile warnings if we have unhandled cases */
+       default:
+               return IN_UIL1_G711ULAW;
        }
        return IN_UIL1_G711ULAW;
 }
@@ -1107,7 +1110,7 @@ ftdm_bearer_cap_t sngisdn_get_infoTranCap_from_stack(uint8_t bearer_capability)
        case IN_ITC_SPEECH:
                return FTDM_BEARER_CAP_SPEECH;          
        case IN_ITC_UNRDIG:
-               return FTDM_BEARER_CAP_64K_UNRESTRICTED;                
+               return FTDM_BEARER_CAP_UNRESTRICTED;
        case IN_ITC_A31KHZ:
                return FTDM_BEARER_CAP_3_1KHZ_AUDIO;
        default:
index 596ae7c734d05657007e868c0da272a33e07d2db..0520e9d163a2555a5e0a22833f1df09a655a5336 100644 (file)
 
 /* INCLUDE ********************************************************************/
 #include "ftmod_sangoma_ss7_main.h"
+
 /******************************************************************************/
 
 /* DEFINES ********************************************************************/
 /******************************************************************************/
 
 /* GLOBALS ********************************************************************/
+
 /******************************************************************************/
 
 /* PROTOTYPES *****************************************************************/
@@ -79,14 +81,14 @@ ftdm_status_t handle_olm_msg(uint32_t suInstId, uint32_t spInstId, uint32_t circ
 /******************************************************************************/
 
 /* 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 = NULL;
        ftdm_channel_t          *ftdmchan = NULL;
        char                            nadi[2];
-
+       
+       SS7_FUNC_TRACE_ENTER(__FUNCTION__);
        memset(nadi, '\0', sizeof(nadi));
 
        /* get the ftdmchan and ss7_chan_data from the circuit */
@@ -208,6 +210,10 @@ ftdm_status_t handle_con_ind(uint32_t suInstId, uint32_t spInstId, uint32_t circ
                        sprintf(nadi, "%d", siConEvnt->cdPtyNum.natAddrInd.val);
                        sngss7_add_var(sngss7_info, "ss7_cld_nadi", nadi);
 
+                       if (sngss7_info->circuit->transparent_iam) {
+                               sngss7_save_iam(ftdmchan, siConEvnt);
+                       }
+
                        /* check if a COT test is requested */
                        if ((siConEvnt->natConInd.eh.pres) && 
                                (siConEvnt->natConInd.contChkInd.pres) &&
@@ -231,7 +237,6 @@ ftdm_status_t handle_con_ind(uint32_t suInstId, uint32_t spInstId, uint32_t circ
                                                        siConEvnt->cgPtyNum.natAddrInd.val,
                                                        ftdmchan->caller_data.dnis.digits,
                                                        siConEvnt->cdPtyNum.natAddrInd.val);
-
                } /* if (channel is usable */
 
                break;
index 4f8c069b7104cfadfa33131c078ed59c90b5042f..53062b9d56955b6289a5dfb0dd17600475f04bea 100644 (file)
@@ -42,6 +42,7 @@
 static sng_isup_event_interface_t sng_event;
 static ftdm_io_interface_t g_ftdm_sngss7_interface;
 ftdm_sngss7_data_t g_ftdm_sngss7_data;
+
 /******************************************************************************/
 
 /* PROTOTYPES *****************************************************************/
@@ -509,11 +510,6 @@ ftdm_status_t ftdm_sangoma_ss7_process_state_change (ftdm_channel_t * ftdmchan)
 
        SS7_DEBUG_CHAN(ftdmchan, "ftmod_sangoma_ss7 processing state %s\n", ftdm_channel_state2str (ftdmchan->state));
 
-#if 0
-       /* clear the state change flag...since we might be setting a new state */
-       ftdm_channel_complete_state(ftdmchan);
-#endif
-
        /*check what state we are supposed to be in */
        switch (ftdmchan->state) {
        /**************************************************************************/
index 04723048f6972eb629a8dbda29adb93669b0aee0..f88202b1a879d9548850c9005504ae664b3f16ad 100644 (file)
@@ -339,6 +339,7 @@ typedef struct sng_isup_ckt {
                        
        uint32_t                min_digits;
        uint8_t                 itx_auto_reply;
+       uint8_t                 transparent_iam;
        void                    *obj;
        uint16_t                t3;
        uint16_t                t12;
@@ -406,6 +407,7 @@ typedef struct sng_ss7_cfg {
        uint32_t                        procId;
        char                            license[MAX_PATH];
        char                            signature[MAX_PATH];
+       uint32_t                        transparent_iam_max_size;
        uint32_t                        flags;
        sng_relay_t                     relay[MAX_RELAY_CHANNELS+1];
        sng_mtp1_link_t         mtp1Link[MAX_MTP_LINKS+1];
@@ -765,6 +767,10 @@ void sngss7_resm_ind(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, SiR
 void sngss7_susp_ind(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, SiSuspEvnt *siSuspEvnt);
 void sngss7_ssp_sta_cfm(uint32_t infId);
 
+ftdm_status_t sngss7_bufferzero_iam(SiConEvnt *siConEvnt);
+ftdm_status_t sngss7_retrieve_iam(ftdm_channel_t *ftdmchan, SiConEvnt *siConEvnt);
+ftdm_status_t sngss7_save_iam(ftdm_channel_t *ftdmchan, SiConEvnt *siConEvnt);
+
 /* in ftmod_sangoma_ss7_handle.c */
 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);
@@ -815,6 +821,11 @@ ftdm_status_t copy_genNmb_to_sngss7(ftdm_channel_t *ftdmchan, SiGenNum *genNmb);
 ftdm_status_t copy_genNmb_from_sngss7(ftdm_channel_t *ftdmchan, SiGenNum *genNmb);
 ftdm_status_t copy_cgPtyCat_to_sngss7(ftdm_channel_t *ftdmchan, SiCgPtyCat *cgPtyCat);
 ftdm_status_t copy_cgPtyCat_from_sngss7(ftdm_channel_t *ftdmchan, SiCgPtyCat *cgPtyCat);
+ftdm_status_t copy_accTrnspt_to_sngss7(ftdm_channel_t *ftdmchan, SiAccTrnspt *accTrnspt);
+ftdm_status_t copy_natConInd_to_sngss7(ftdm_channel_t *ftdmchan, SiNatConInd *natConInd);
+ftdm_status_t copy_fwdCallInd_to_sngss7(ftdm_channel_t *ftdmchan, SiFwdCallInd *fwdCallInd);
+ftdm_status_t copy_txMedReq_to_sngss7(ftdm_channel_t *ftdmchan, SiTxMedReq *txMedReq);
+ftdm_status_t copy_usrServInfoA_to_sngss7(ftdm_channel_t *ftdmchan, SiUsrServInfo *usrServInfoA);
 
 ftdm_status_t copy_tknStr_from_sngss7(TknStr str, char *ftdm, TknU8 oddEven);
 ftdm_status_t append_tknStr_from_sngss7(TknStr str, char *ftdm, TknU8 oddEven);
index e1944513d16b269e71ce65a6d636f5d1a3dc7988..91b8900fef4b2e119cecc1788c25b61021c0e4db 100644 (file)
 /******************************************************************************/
 
 /* DEFINES ********************************************************************/
-/******************************************************************************/
 
 /* GLOBALS ********************************************************************/
-/******************************************************************************/
 
 /* PROTOTYPES *****************************************************************/
 void ft_to_sngss7_iam(ftdm_channel_t * ftdmchan);
@@ -66,219 +64,70 @@ void ft_to_sngss7_cgu(ftdm_channel_t * ftdmchan);
 
 void ft_to_sngss7_cgba(ftdm_channel_t * ftdmchan);
 void ft_to_sngss7_cgua(ftdm_channel_t * ftdmchan);
-/******************************************************************************/
 
 /* FUNCTIONS ******************************************************************/
 void ft_to_sngss7_iam (ftdm_channel_t * ftdmchan)
-{
-       SS7_FUNC_TRACE_ENTER (__FUNCTION__);
-       
-       sngss7_chan_data_t      *sngss7_info = ftdmchan->call_data;;
-       const char                      *clg_subAddr = NULL;
-       const char                      *cld_subAddr = NULL;
-       char                            subAddrIE[MAX_SIZEOF_SUBADDR_IE];
+{      
        SiConEvnt                       iam;
+       sngss7_chan_data_t      *sngss7_info = ftdmchan->call_data;;
+       
+       SS7_FUNC_TRACE_ENTER (__FUNCTION__);
        
        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_PREFAW;
-       iam.fwdCallInd.isdnAccInd.pres          = PRSNT_NODEF;
-       iam.fwdCallInd.isdnAccInd.val           = ISDNACC_ISDN;
-       iam.fwdCallInd.sccpMethInd.pres         = PRSNT_NODEF;
-       iam.fwdCallInd.sccpMethInd.val          = SCCPMTH_NOIND;
+
+       if (sngss7_info->circuit->transparent_iam &&
+               sngss7_retrieve_iam(ftdmchan, &iam) == FTDM_SUCCESS) {
+               SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Tx IAM (Transparent)\n", sngss7_info->circuit->cic);
+       } else {
+               /* Nature of Connection Indicators */
+               copy_natConInd_to_sngss7(ftdmchan, &iam.natConInd);
+
+               /* Forward Call Indicators */
+               copy_fwdCallInd_to_sngss7(ftdmchan, &iam.fwdCallInd);
+
+               /* Transmission medium requirements */
+               copy_txMedReq_to_sngss7(ftdmchan, &iam.txMedReq);
+
+               /* User Service Info A */
+               copy_usrServInfoA_to_sngss7(ftdmchan, &iam.usrServInfoA);
                
-       /* 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;
-
-       if ((g_ftdm_sngss7_data.cfg.isupCkt[sngss7_info->circuit->id].switchType == LSI_SW_ANS88) ||
-               (g_ftdm_sngss7_data.cfg.isupCkt[sngss7_info->circuit->id].switchType == LSI_SW_ANS92) ||
-               (g_ftdm_sngss7_data.cfg.isupCkt[sngss7_info->circuit->id].switchType == LSI_SW_ANS95)) {
-
-               /* include only if we're running ANSI */
-               iam.fwdCallInd.transCallNInd.pres   = PRSNT_NODEF;
-               iam.fwdCallInd.transCallNInd.val    = 0x0;
-
-               iam.usrServInfoA.eh.pres                                = PRSNT_NODEF;
-
-               iam.usrServInfoA.infoTranCap.pres               = PRSNT_NODEF;
-               switch (ftdmchan->caller_data.bearer_capability) {
-               /**********************************************************************/
-               case (FTDM_BEARER_CAP_SPEECH):
-                       iam.usrServInfoA.infoTranCap.val        = 0x0;                  /* speech as per ATIS-1000113.3.2005 */
-                       break;
-               /**********************************************************************/
-               case (FTDM_BEARER_CAP_64K_UNRESTRICTED):
-                       iam.usrServInfoA.infoTranCap.val        = 0x8;                  /* unrestricted digital as per ATIS-1000113.3.2005 */
-                       break;
-               /**********************************************************************/
-               case (FTDM_BEARER_CAP_3_1KHZ_AUDIO):
-                       iam.usrServInfoA.infoTranCap.val        = 0x10;                 /* 3.1kHz audio as per ATIS-1000113.3.2005 */
-                       break;
-               /**********************************************************************/
-               default:
-                       SS7_ERROR_CHAN(ftdmchan, "Unknown Bearer capability falling back to speech%s\n", " ");
-                       iam.usrServInfoA.infoTranCap.val        = 0x0;                  /* speech as per ATIS-1000113.3.2005 */
-                       break;
-               /**********************************************************************/
-               } /* switch (ftdmchan->caller_data.bearer_capability) */
-
-               iam.usrServInfoA.cdeStand.pres                  = PRSNT_NODEF;
-               iam.usrServInfoA.cdeStand.val                   = 0x0;                          /* ITU-T standardized coding */
-               iam.usrServInfoA.tranMode.pres                  = PRSNT_NODEF;
-               iam.usrServInfoA.tranMode.val                   = 0x0;                          /* circuit mode */
-               iam.usrServInfoA.infoTranRate0.pres             = PRSNT_NODEF;
-               iam.usrServInfoA.infoTranRate0.val              = 0x10;                         /* 64kbps origination to destination */
-               iam.usrServInfoA.infoTranRate1.pres             = PRSNT_NODEF;
-               iam.usrServInfoA.infoTranRate1.val              = 0x10;                         /* 64kbps destination to origination */
-               iam.usrServInfoA.chanStruct.pres                = PRSNT_NODEF;
-               iam.usrServInfoA.chanStruct.val                 = 0x1;                          /* 8kHz integrity */
-               iam.usrServInfoA.config.pres                    = PRSNT_NODEF;
-               iam.usrServInfoA.config.val                             = 0x0;                          /* point to point configuration */
-               iam.usrServInfoA.establish.pres                 = PRSNT_NODEF;
-               iam.usrServInfoA.establish.val                  = 0x0;                          /* on demand */
-               iam.usrServInfoA.symmetry.pres                  = PRSNT_NODEF;
-               iam.usrServInfoA.symmetry.val                   = 0x0;                          /* bi-directional symmetric */
-               iam.usrServInfoA.usrInfLyr1Prot.pres    = PRSNT_NODEF;
-               iam.usrServInfoA.usrInfLyr1Prot.val             = 0x2;                          /* G.711 ulaw */
-               iam.usrServInfoA.rateMultiplier.pres    = PRSNT_NODEF;
-               iam.usrServInfoA.rateMultiplier.val             = 0x1;                          /* 1x rate multipler */
-       } /* if ANSI */
-
-       /* copy down the called number information */
-       copy_cdPtyNum_to_sngss7 (ftdmchan, &iam.cdPtyNum);
-       
-       /* copy down the calling number information */  
-       copy_cgPtyNum_to_sngss7 (ftdmchan, &iam.cgPtyNum);
-
-       /* copy down the generic number information */
-       copy_genNmb_to_sngss7(ftdmchan, &iam.genNmb);
-
-       /* copy down the calling party category */
-       copy_cgPtyCat_to_sngss7(ftdmchan, &iam.cgPtyCat);
-       
-       /* TODO - move this to copy_clg_subAddr_to_sngss7 function */
-       /* check if the user would like us to send a clg_sub-address */
-       clg_subAddr = ftdm_usrmsg_get_var(ftdmchan->usrmsg, "ss7_clg_subaddr");
-       if (!ftdm_strlen_zero(clg_subAddr)) {
-               SS7_DEBUG_CHAN(ftdmchan,"Found user supplied Calling Sub-Address value \"%s\"\n", clg_subAddr);
+               /* Called Number information */
+               copy_cdPtyNum_to_sngss7(ftdmchan, &iam.cdPtyNum);
                
-               /* clean out the subAddrIE */
-               memset(subAddrIE, 0x0, sizeof(subAddrIE));
-
-               /* check the first character in the sub-address to see what type of encoding to use */
-               switch (clg_subAddr[0]) {
-               case '0':                                               /* NSAP */
-                       encode_subAddrIE_nsap(&clg_subAddr[1], subAddrIE, SNG_CALLING);
-                       break;
-               case '1':                                               /* national variant */
-                       encode_subAddrIE_nat(&clg_subAddr[1], subAddrIE, SNG_CALLING);
-                       break;
-               default:
-                       SS7_ERROR_CHAN(ftdmchan,"Invalid Calling Sub-Address encoding requested: %c\n", clg_subAddr[0]);
-                       break;
-               } /* switch (cld_subAddr[0]) */
-
-
-               /* if subaddIE is still empty don't copy it in */
-               if (subAddrIE[0] != '0') {
-                       /* check if the clg_subAddr has already been added */
-                       if (iam.accTrnspt.eh.pres == PRSNT_NODEF) {
-                               /* append the subAddrIE */
-                               memcpy(&iam.accTrnspt.infoElmts.val[iam.accTrnspt.infoElmts.len], subAddrIE, (subAddrIE[1] + 2));
-                               iam.accTrnspt.infoElmts.len             = iam.accTrnspt.infoElmts.len +subAddrIE[1] + 2;
-                       } else {
-                               /* fill in from the beginning */
-                               iam.accTrnspt.eh.pres                   = PRSNT_NODEF;
-                               iam.accTrnspt.infoElmts.pres    = PRSNT_NODEF;
-                               memcpy(iam.accTrnspt.infoElmts.val, subAddrIE, (subAddrIE[1] + 2));
-                               iam.accTrnspt.infoElmts.len             = subAddrIE[1] + 2;
-                       } /* if (iam.accTrnspt.eh.pres */
-               } /* if (subAddrIE[0] != '0') */
-       }
+               /* Calling Number information */
+               copy_cgPtyNum_to_sngss7(ftdmchan, &iam.cgPtyNum);
 
-       copy_redirgNum_to_sngss7(ftdmchan, &iam.redirgNum);
-       
-       /* check if the user would like us to send a cld_sub-address */
-       cld_subAddr = ftdm_usrmsg_get_var(ftdmchan->usrmsg, "ss7_cld_subaddr");
-       if ((cld_subAddr != NULL) && (*cld_subAddr)) {
-               SS7_DEBUG_CHAN(ftdmchan,"Found user supplied Called Sub-Address value \"%s\"\n", cld_subAddr);
-               
-               /* clean out the subAddrIE */
-               memset(subAddrIE, 0x0, sizeof(subAddrIE));
-
-               /* check the first character in the sub-address to see what type of encoding to use */
-               switch (cld_subAddr[0]) {
-               case '0':                                               /* NSAP */
-                       encode_subAddrIE_nsap(&cld_subAddr[1], subAddrIE, SNG_CALLED);
-                       break;
-               case '1':                                               /* national variant */
-                       encode_subAddrIE_nat(&cld_subAddr[1], subAddrIE, SNG_CALLED);
-                       break;
-               default:
-                       SS7_ERROR_CHAN(ftdmchan,"Invalid Called Sub-Address encoding requested: %c\n", cld_subAddr[0]);
-                       break;
-               } /* switch (cld_subAddr[0]) */
-
-               /* if subaddIE is still empty don't copy it in */
-               if (subAddrIE[0] != '0') {
-                       /* check if the cld_subAddr has already been added */
-                       if (iam.accTrnspt.eh.pres == PRSNT_NODEF) {
-                               /* append the subAddrIE */
-                               memcpy(&iam.accTrnspt.infoElmts.val[iam.accTrnspt.infoElmts.len], subAddrIE, (subAddrIE[1] + 2));
-                               iam.accTrnspt.infoElmts.len             = iam.accTrnspt.infoElmts.len +subAddrIE[1] + 2;
-                       } else {
-                               /* fill in from the beginning */
-                               iam.accTrnspt.eh.pres                   = PRSNT_NODEF;
-                               iam.accTrnspt.infoElmts.pres    = PRSNT_NODEF;
-                               memcpy(iam.accTrnspt.infoElmts.val, subAddrIE, (subAddrIE[1] + 2));
-                               iam.accTrnspt.infoElmts.len             = subAddrIE[1] + 2;
-                       } /* if (iam.accTrnspt.eh.pres */
-               } /* if (subAddrIE[0] != '0') */
-       } /* if ((cld_subAddr != NULL) && (*cld_subAddr)) */
+               /* Generic Number information */
+               copy_genNmb_to_sngss7(ftdmchan, &iam.genNmb);
+
+               /* Calling Party's Category */
+               copy_cgPtyCat_to_sngss7(ftdmchan, &iam.cgPtyCat);
+
+               /* Redirecting Number */
+               copy_redirgNum_to_sngss7(ftdmchan, &iam.redirgNum);
+
+               /* Access Transport */
+               copy_accTrnspt_to_sngss7(ftdmchan, &iam.accTrnspt);
+
+               SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Tx IAM clg = \"%s\" (NADI=%d), cld = \"%s\" (NADI=%d)\n",
+                                                                       sngss7_info->circuit->cic,
+                                                                       ftdmchan->caller_data.cid_num.digits,
+                                                                       iam.cgPtyNum.natAddrInd.val,
+                                                                       ftdmchan->caller_data.dnis.digits,
+                                                                       iam.cdPtyNum.natAddrInd.val);
+       }
 
        sng_cc_con_request (sngss7_info->spId,
                                                sngss7_info->suInstId,
                                                sngss7_info->spInstId,
-                                               sngss7_info->circuit->id, 
-                                               &iam, 
+                                               sngss7_info->circuit->id,
+                                               &iam,
                                                0);
 
-       SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Tx IAM clg = \"%s\" (NADI=%d), cld = \"%s\" (NADI=%d)\n",
-                                                       sngss7_info->circuit->cic,
-                                                       ftdmchan->caller_data.cid_num.digits,
-                                                       iam.cgPtyNum.natAddrInd.val,
-                                                       ftdmchan->caller_data.dnis.digits,
-                                                       iam.cdPtyNum.natAddrInd.val);
-
-
        SS7_FUNC_TRACE_EXIT (__FUNCTION__);
        return;
 }
@@ -319,7 +168,7 @@ void ft_to_sngss7_acm (ftdm_channel_t * ftdmchan)
                acm.bckCallInd.echoCtrlDevInd.val       = 0x1;
                break;
        /**********************************************************************/
-       case (FTDM_BEARER_CAP_64K_UNRESTRICTED):
+       case (FTDM_BEARER_CAP_UNRESTRICTED):
                acm.bckCallInd.echoCtrlDevInd.val       = 0x0;
                break;
        /**********************************************************************/
index 3ebd162f09bfd5d35a5850c8e95995bcf16a2a72..e61153c8e7b7afc32b2f80be04cb68e0dc4ce0a8 100644 (file)
@@ -33,6 +33,9 @@
 
 /* INCLUDE ********************************************************************/
 #include "ftmod_sangoma_ss7_main.h"
+#ifdef HAVE_ZLIB
+#include <zlib.h>
+#endif
 /******************************************************************************/
 
 /* DEFINES ********************************************************************/
@@ -111,6 +114,16 @@ ftdm2trillium_t cpc_codes[] = {
        {FTDM_CPC_PAYPHONE,                     CAT_PAYPHONE},
 };
 
+ftdm2trillium_t  bc_cap_codes[] = {
+       {FTDM_BEARER_CAP_SPEECH,                ITC_SPEECH},    /* speech as per ATIS-1000113.3.2005 */
+       {FTDM_BEARER_CAP_UNRESTRICTED,  ITC_UNRDIG},    /* unrestricted digital as per ATIS-1000113.3.2005 */
+       {FTDM_BEARER_CAP_RESTRICTED,    ITC_UNRDIG},    /* Restricted Digital */
+       {FTDM_BEARER_CAP_3_1KHZ_AUDIO,  ITC_A31KHZ},    /* 3.1kHz audio as per ATIS-1000113.3.2005 */
+       {FTDM_BEARER_CAP_7KHZ_AUDIO,    ITC_A7KHZ},             /* 7Khz audio */
+       {FTDM_BEARER_CAP_15KHZ_AUDIO,   ITC_A15KHZ},    /* 15Khz audio */
+       {FTDM_BEARER_CAP_VIDEO,                 ITC_VIDEO},             /* Video */
+};
+
 static uint8_t get_trillium_val(ftdm2trillium_t *vals, uint8_t ftdm_val, uint8_t default_val)
 {
        ftdm2trillium_t *val = vals;
@@ -485,6 +498,187 @@ ftdm_status_t copy_cgPtyCat_from_sngss7(ftdm_channel_t *ftdmchan, SiCgPtyCat *cg
        return FTDM_SUCCESS;
 }
 
+
+ftdm_status_t copy_accTrnspt_to_sngss7(ftdm_channel_t *ftdmchan, SiAccTrnspt *accTrnspt)
+{
+       const char                      *clg_subAddr = NULL;
+       const char                      *cld_subAddr = NULL;
+       char                            subAddrIE[MAX_SIZEOF_SUBADDR_IE];
+       
+       /* check if the user would like us to send a clg_sub-address */
+       clg_subAddr = ftdm_usrmsg_get_var(ftdmchan->usrmsg, "ss7_clg_subaddr");
+       if (!ftdm_strlen_zero(clg_subAddr)) {
+               ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "Found user supplied Calling Sub-Address value \"%s\"\n", clg_subAddr);
+               
+               /* clean out the subAddrIE */
+               memset(subAddrIE, 0x0, sizeof(subAddrIE));
+
+               /* check the first character in the sub-address to see what type of encoding to use */
+               switch (clg_subAddr[0]) {
+                       case '0':                                               /* NSAP */
+                               encode_subAddrIE_nsap(&clg_subAddr[1], subAddrIE, SNG_CALLING);
+                               break;
+                               case '1':                                               /* national variant */
+                                       encode_subAddrIE_nat(&clg_subAddr[1], subAddrIE, SNG_CALLING);
+                                       break;
+                       default:
+                               ftdm_log_chan(ftdmchan, FTDM_LOG_ERROR, "Invalid Calling Sub-Address encoding requested: %c\n", clg_subAddr[0]);
+                               break;
+               } /* switch (cld_subAddr[0]) */
+
+
+               /* if subaddIE is still empty don't copy it in */
+               if (subAddrIE[0] != '0') {
+                       /* check if the clg_subAddr has already been added */
+                       if (accTrnspt->eh.pres == PRSNT_NODEF) {
+                               /* append the subAddrIE */
+                               memcpy(&accTrnspt->infoElmts.val[accTrnspt->infoElmts.len], subAddrIE, (subAddrIE[1] + 2));
+                               accTrnspt->infoElmts.len                = accTrnspt->infoElmts.len +subAddrIE[1] + 2;
+                       } else {
+                               /* fill in from the beginning */
+                               accTrnspt->eh.pres                      = PRSNT_NODEF;
+                               accTrnspt->infoElmts.pres       = PRSNT_NODEF;
+                               memcpy(accTrnspt->infoElmts.val, subAddrIE, (subAddrIE[1] + 2));
+                               accTrnspt->infoElmts.len                = subAddrIE[1] + 2;
+                       }
+               }
+       }       
+
+       /* check if the user would like us to send a cld_sub-address */
+       cld_subAddr = ftdm_usrmsg_get_var(ftdmchan->usrmsg, "ss7_cld_subaddr");
+       if ((cld_subAddr != NULL) && (*cld_subAddr)) {
+               ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "Found user supplied Called Sub-Address value \"%s\"\n", cld_subAddr);
+               
+               /* clean out the subAddrIE */
+               memset(subAddrIE, 0x0, sizeof(subAddrIE));
+
+               /* check the first character in the sub-address to see what type of encoding to use */
+               switch (cld_subAddr[0]) {
+                       case '0':                                               /* NSAP */
+                               encode_subAddrIE_nsap(&cld_subAddr[1], subAddrIE, SNG_CALLED);
+                               break;
+                               case '1':                                               /* national variant */
+                                       encode_subAddrIE_nat(&cld_subAddr[1], subAddrIE, SNG_CALLED);
+                                       break;
+                       default:
+                               ftdm_log_chan(ftdmchan, FTDM_LOG_ERROR, "Invalid Called Sub-Address encoding requested: %c\n", cld_subAddr[0]);
+                               break;
+               } /* switch (cld_subAddr[0]) */
+
+               /* if subaddIE is still empty don't copy it in */
+               if (subAddrIE[0] != '0') {
+                       /* check if the cld_subAddr has already been added */
+                       if (accTrnspt->eh.pres == PRSNT_NODEF) {
+                               /* append the subAddrIE */
+                               memcpy(&accTrnspt->infoElmts.val[accTrnspt->infoElmts.len], subAddrIE, (subAddrIE[1] + 2));
+                               accTrnspt->infoElmts.len                = accTrnspt->infoElmts.len +subAddrIE[1] + 2;
+                       } else {
+                               /* fill in from the beginning */
+                               accTrnspt->eh.pres                      = PRSNT_NODEF;
+                               accTrnspt->infoElmts.pres       = PRSNT_NODEF;
+                               memcpy(accTrnspt->infoElmts.val, subAddrIE, (subAddrIE[1] + 2));
+                               accTrnspt->infoElmts.len                = subAddrIE[1] + 2;
+                       }
+               }
+       } /* if ((cld_subAddr != NULL) && (*cld_subAddr)) */
+       return FTDM_SUCCESS;
+}
+
+ftdm_status_t copy_natConInd_to_sngss7(ftdm_channel_t *ftdmchan, SiNatConInd *natConInd)
+{
+       /* copy down the nature of connection indicators */
+       natConInd->eh.pres                              = PRSNT_NODEF;
+       natConInd->satInd.pres                  = PRSNT_NODEF;
+       natConInd->satInd.val                   = 0; /* no satellite circuit */
+       natConInd->contChkInd.pres              = PRSNT_NODEF;
+       natConInd->contChkInd.val               = CONTCHK_NOTREQ;
+       natConInd->echoCntrlDevInd.pres = PRSNT_NODEF;
+       natConInd->echoCntrlDevInd.val  = ECHOCDEV_INCL;
+       return FTDM_SUCCESS;
+}
+
+ftdm_status_t copy_fwdCallInd_to_sngss7(ftdm_channel_t *ftdmchan, SiFwdCallInd *fwdCallInd)
+{
+       sngss7_chan_data_t      *sngss7_info = ftdmchan->call_data;
+       
+       fwdCallInd->eh.pres                             = PRSNT_NODEF;
+       fwdCallInd->natIntCallInd.pres          = PRSNT_NODEF;
+       fwdCallInd->natIntCallInd.val           = 0x00;
+       fwdCallInd->end2EndMethInd.pres         = PRSNT_NODEF;
+       fwdCallInd->end2EndMethInd.val          = E2EMTH_NOMETH;
+       fwdCallInd->intInd.pres                         = PRSNT_NODEF;
+       fwdCallInd->intInd.val                          = INTIND_NOINTW;
+       fwdCallInd->end2EndInfoInd.pres         = PRSNT_NODEF;
+       fwdCallInd->end2EndInfoInd.val          = E2EINF_NOINFO;
+       fwdCallInd->isdnUsrPrtInd.pres          = PRSNT_NODEF;
+       fwdCallInd->isdnUsrPrtInd.val           = ISUP_USED;
+       fwdCallInd->isdnUsrPrtPrfInd.pres       = PRSNT_NODEF;
+       fwdCallInd->isdnUsrPrtPrfInd.val        = PREF_PREFAW;
+       fwdCallInd->isdnAccInd.pres             = PRSNT_NODEF;
+       fwdCallInd->isdnAccInd.val                      = ISDNACC_ISDN;
+       fwdCallInd->sccpMethInd.pres            = PRSNT_NODEF;
+       fwdCallInd->sccpMethInd.val             = SCCPMTH_NOIND;
+
+       if ((g_ftdm_sngss7_data.cfg.isupCkt[sngss7_info->circuit->id].switchType == LSI_SW_ANS88) ||
+               (g_ftdm_sngss7_data.cfg.isupCkt[sngss7_info->circuit->id].switchType == LSI_SW_ANS92) ||
+               (g_ftdm_sngss7_data.cfg.isupCkt[sngss7_info->circuit->id].switchType == LSI_SW_ANS95)) {
+
+               /* include only if we're running ANSI */
+               fwdCallInd->transCallNInd.pres   = PRSNT_NODEF;
+               fwdCallInd->transCallNInd.val    = 0x0;
+       }
+       return FTDM_SUCCESS;
+}
+
+ftdm_status_t copy_txMedReq_to_sngss7(ftdm_channel_t *ftdmchan, SiTxMedReq *txMedReq)
+{
+       txMedReq->eh.pres               = PRSNT_NODEF;
+       txMedReq->trMedReq.pres = PRSNT_NODEF;
+       txMedReq->trMedReq.val  = ftdmchan->caller_data.bearer_capability;
+
+       return FTDM_SUCCESS;
+}
+
+ftdm_status_t copy_usrServInfoA_to_sngss7(ftdm_channel_t *ftdmchan, SiUsrServInfo *usrServInfoA)
+{
+       sngss7_chan_data_t      *sngss7_info = ftdmchan->call_data;
+       
+       if ((g_ftdm_sngss7_data.cfg.isupCkt[sngss7_info->circuit->id].switchType == LSI_SW_ANS88) ||
+               (g_ftdm_sngss7_data.cfg.isupCkt[sngss7_info->circuit->id].switchType == LSI_SW_ANS92) ||
+               (g_ftdm_sngss7_data.cfg.isupCkt[sngss7_info->circuit->id].switchType == LSI_SW_ANS95)) {
+
+               usrServInfoA->eh.pres                   = PRSNT_NODEF;
+
+               usrServInfoA->infoTranCap.pres  = PRSNT_NODEF;
+               
+               usrServInfoA->infoTranCap.val = get_trillium_val(bc_cap_codes, ftdmchan->caller_data.bearer_capability, ITC_SPEECH);
+
+               usrServInfoA->cdeStand.pres                     = PRSNT_NODEF;
+               usrServInfoA->cdeStand.val                      = 0x0;                          /* ITU-T standardized coding */
+               usrServInfoA->tranMode.pres                     = PRSNT_NODEF;
+               usrServInfoA->tranMode.val                      = 0x0;                          /* circuit mode */
+               usrServInfoA->infoTranRate0.pres                = PRSNT_NODEF;
+               usrServInfoA->infoTranRate0.val         = 0x10;                         /* 64kbps origination to destination */
+               usrServInfoA->infoTranRate1.pres                = PRSNT_NODEF;
+               usrServInfoA->infoTranRate1.val         = 0x10;                         /* 64kbps destination to origination */
+               usrServInfoA->chanStruct.pres           = PRSNT_NODEF;
+               usrServInfoA->chanStruct.val                    = 0x1;                          /* 8kHz integrity */
+               usrServInfoA->config.pres                       = PRSNT_NODEF;
+               usrServInfoA->config.val                                = 0x0;                          /* point to point configuration */
+               usrServInfoA->establish.pres                    = PRSNT_NODEF;
+               usrServInfoA->establish.val                     = 0x0;                          /* on demand */
+               usrServInfoA->symmetry.pres                     = PRSNT_NODEF;
+               usrServInfoA->symmetry.val                      = 0x0;                          /* bi-directional symmetric */
+               usrServInfoA->usrInfLyr1Prot.pres       = PRSNT_NODEF;
+               usrServInfoA->usrInfLyr1Prot.val                = 0x2;                          /* G.711 ulaw */
+               usrServInfoA->rateMultiplier.pres       = PRSNT_NODEF;
+               usrServInfoA->rateMultiplier.val                = 0x1;                          /* 1x rate multipler */
+       } /* if ANSI */
+       return FTDM_SUCCESS;
+}
+
+
+
 ftdm_status_t copy_tknStr_from_sngss7(TknStr str, char *ftdm, TknU8 oddEven)
 {
        uint8_t i;
@@ -1724,7 +1918,7 @@ void sngss7_set_sig_status(sngss7_chan_data_t *sngss7_info, ftdm_signaling_statu
        sig.ev_data.sigstatus.status = status;
 
        if (ftdm_span_send_signal(ftdmchan->span, &sig) != FTDM_SUCCESS) {
-               SS7_ERROR_CHAN(ftdmchan, "Failed to change channel status to %s\n", 
+               ftdm_log_chan(ftdmchan, FTDM_LOG_ERROR,  "Failed to change channel status to %s\n",
                                                                        ftdm_signaling_status2str(status));
        }
        return;
@@ -1899,6 +2093,336 @@ ftdm_status_t check_for_reconfig_flag(ftdm_span_t *ftdmspan)
 
        return FTDM_SUCCESS;
 }
+
+ftdm_status_t sngss7_bufferzero_iam(SiConEvnt *siConEvnt)
+{
+       if (siConEvnt->natConInd.eh.pres != PRSNT_NODEF) memset(&siConEvnt->natConInd, 0, sizeof(siConEvnt->natConInd));        
+       if (siConEvnt->fwdCallInd.eh.pres != PRSNT_NODEF) memset(&siConEvnt->fwdCallInd, 0, sizeof(siConEvnt->fwdCallInd));
+       if (siConEvnt->cgPtyCat.eh.pres != PRSNT_NODEF) memset(&siConEvnt->cgPtyCat, 0, sizeof(siConEvnt->cgPtyCat));
+       if (siConEvnt->txMedReq.eh.pres != PRSNT_NODEF) memset(&siConEvnt->txMedReq, 0, sizeof(siConEvnt->txMedReq));
+#if (SS7_ANS88 || SS7_ANS92 || SS7_ANS95 || SS7_BELL)  
+       if (siConEvnt->usrServInfoA.eh.pres != PRSNT_NODEF) memset(&siConEvnt->usrServInfoA, 0, sizeof(siConEvnt->usrServInfoA));
+#endif 
+       if (siConEvnt->cdPtyNum.eh.pres != PRSNT_NODEF) memset(&siConEvnt->cdPtyNum, 0, sizeof(siConEvnt->cdPtyNum));
+#if TNS_ANSI
+#if (SS7_ANS92 || SS7_ANS95 || SS7_BELL)
+       if (siConEvnt->tranNetSel1.eh.pres != PRSNT_NODEF) memset(&siConEvnt->tranNetSel1, 0, sizeof(siConEvnt->tranNetSel1));
+#endif
+#endif
+       if (siConEvnt->tranNetSel.eh.pres != PRSNT_NODEF) memset(&siConEvnt->tranNetSel, 0, sizeof(siConEvnt->tranNetSel));
+#if (SS7_ANS88 || SS7_ANS92 || SS7_ANS95 || SS7_BELL || SS7_CHINA)
+       if (siConEvnt->callRefA.eh.pres != PRSNT_NODEF) memset(&siConEvnt->callRefA, 0, sizeof(siConEvnt->callRefA));
+#endif
+       if (siConEvnt->callRef.eh.pres != PRSNT_NODEF) memset(&siConEvnt->callRef, 0, sizeof(siConEvnt->callRef));
+       if (siConEvnt->cgPtyNum.eh.pres != PRSNT_NODEF) memset(&siConEvnt->cgPtyNum, 0, sizeof(siConEvnt->cgPtyNum));
+#if SS7_BELL
+       if (siConEvnt->cgPtyNumB.eh.pres != PRSNT_NODEF) memset(&siConEvnt->cgPtyNumB, 0, sizeof(siConEvnt->cgPtyNumB));
+#endif
+       if (siConEvnt->opFwdCalInd.eh.pres != PRSNT_NODEF) memset(&siConEvnt->opFwdCalInd, 0, sizeof(siConEvnt->opFwdCalInd));
+#if (SS7_Q767 || SS7_RUSSIA || SS7_NTT)        
+       if (siConEvnt->opFwdCalIndQ.eh.pres != PRSNT_NODEF) memset(&siConEvnt->opFwdCalIndQ, 0, sizeof(siConEvnt->opFwdCalIndQ));
+#endif
+#if SS7_Q767IT
+       if (siConEvnt->fwdVad.eh.pres != PRSNT_NODEF) memset(&siConEvnt->fwdVad, 0, sizeof(siConEvnt->fwdVad));
+#endif
+#if SS7_ANS88
+       if (siConEvnt->opFwdCalIndA.eh.pres != PRSNT_NODEF) memset(&siConEvnt->opFwdCalIndA, 0, sizeof(siConEvnt->opFwdCalIndA));
+#endif 
+       if (siConEvnt->redirgNum.eh.pres != PRSNT_NODEF) memset(&siConEvnt->redirgNum, 0, sizeof(siConEvnt->redirgNum));
+       if (siConEvnt->redirInfo.eh.pres != PRSNT_NODEF) memset(&siConEvnt->redirInfo, 0, sizeof(siConEvnt->redirInfo));
+       if (siConEvnt->cugIntCode.eh.pres != PRSNT_NODEF) memset(&siConEvnt->cugIntCode, 0, sizeof(siConEvnt->cugIntCode));
+#if SS7_ANS88
+       if (siConEvnt->cugIntCodeA.eh.pres != PRSNT_NODEF) memset(&siConEvnt->cugIntCodeA, 0, sizeof(siConEvnt->cugIntCodeA));
+#endif
+#if (SS7_ANS88 || SS7_ANS92 || SS7_ANS95 || SS7_BELL || SS7_CHINA)
+       if (siConEvnt->connReqA.eh.pres != PRSNT_NODEF) memset(&siConEvnt->connReqA, 0, sizeof(siConEvnt->connReqA));
+#endif
+#if SS7_ANS88
+       if (siConEvnt->usr2UsrInfoA.eh.pres != PRSNT_NODEF) memset(&siConEvnt->usr2UsrInfoA, 0, sizeof(siConEvnt->usr2UsrInfoA));
+#endif
+       if (siConEvnt->connReq.eh.pres != PRSNT_NODEF) memset(&siConEvnt->connReq, 0, sizeof(siConEvnt->connReq));
+       if (siConEvnt->origCdNum.eh.pres != PRSNT_NODEF) memset(&siConEvnt->origCdNum, 0, sizeof(siConEvnt->origCdNum));
+       if (siConEvnt->usr2UsrInfo.eh.pres != PRSNT_NODEF) memset(&siConEvnt->usr2UsrInfo, 0, sizeof(siConEvnt->usr2UsrInfo));
+       if (siConEvnt->accTrnspt.eh.pres != PRSNT_NODEF) memset(&siConEvnt->accTrnspt, 0, sizeof(siConEvnt->accTrnspt));
+       if (siConEvnt->echoControl.eh.pres != PRSNT_NODEF) memset(&siConEvnt->echoControl, 0, sizeof(siConEvnt->echoControl));
+#if SS7_ANS88
+       if (siConEvnt->redirInfoA.eh.pres != PRSNT_NODEF) memset(&siConEvnt->redirInfoA, 0, sizeof(siConEvnt->redirInfoA));
+#endif
+#if (SS7_ANS88 || SS7_ANS92 || SS7_ANS95 || SS7_BELL)
+       if (siConEvnt->chargeNum.eh.pres != PRSNT_NODEF) memset(&siConEvnt->chargeNum, 0, sizeof(siConEvnt->chargeNum));
+       if (siConEvnt->origLineInf.eh.pres != PRSNT_NODEF) memset(&siConEvnt->origLineInf, 0, sizeof(siConEvnt->origLineInf));
+#endif
+       if (siConEvnt->usrServInfo.eh.pres != PRSNT_NODEF) memset(&siConEvnt->usrServInfo, 0, sizeof(siConEvnt->usrServInfo));
+       if (siConEvnt->usr2UsrInd.eh.pres != PRSNT_NODEF) memset(&siConEvnt->usr2UsrInd, 0, sizeof(siConEvnt->usr2UsrInd));
+       if (siConEvnt->propDly.eh.pres != PRSNT_NODEF) memset(&siConEvnt->propDly, 0, sizeof(siConEvnt->propDly));
+       if (siConEvnt->usrServInfo1.eh.pres != PRSNT_NODEF) memset(&siConEvnt->usrServInfo1, 0, sizeof(siConEvnt->usrServInfo1));
+       if (siConEvnt->netFac.eh.pres != PRSNT_NODEF) memset(&siConEvnt->netFac, 0, sizeof(siConEvnt->netFac));
+#ifdef SS7_CHINA       
+       if (siConEvnt->orgPteCdeA.eh.pres != PRSNT_NODEF) memset(&siConEvnt->orgPteCdeA, 0, sizeof(siConEvnt->orgPteCdeA));
+#endif 
+       if (siConEvnt->orgPteCde.eh.pres != PRSNT_NODEF) memset(&siConEvnt->orgPteCde, 0, sizeof(siConEvnt->orgPteCde));
+       if (siConEvnt->genDigits.eh.pres != PRSNT_NODEF) memset(&siConEvnt->genDigits, 0, sizeof(siConEvnt->genDigits));
+       if (siConEvnt->genDigitsR.eh.pres != PRSNT_NODEF) memset(&siConEvnt->genDigitsR, 0, sizeof(siConEvnt->genDigitsR));
+       if (siConEvnt->usrTSrvInfo.eh.pres != PRSNT_NODEF) memset(&siConEvnt->usrTSrvInfo, 0, sizeof(siConEvnt->usrTSrvInfo));
+       if (siConEvnt->remotOper.eh.pres != PRSNT_NODEF) memset(&siConEvnt->remotOper, 0, sizeof(siConEvnt->remotOper));
+       if (siConEvnt->parmCom.eh.pres != PRSNT_NODEF) memset(&siConEvnt->parmCom, 0, sizeof(siConEvnt->parmCom));
+#if (SS7_ANS92 || SS7_ANS95)
+       if (siConEvnt->servCode.eh.pres != PRSNT_NODEF) memset(&siConEvnt->servCode, 0, sizeof(siConEvnt->servCode));
+#endif
+#if SS7_ANS92
+       if (siConEvnt->serviceAct1.eh.pres != PRSNT_NODEF) memset(&siConEvnt->serviceAct1, 0, sizeof(siConEvnt->serviceAct1));
+#endif
+#if SS7_CHINA
+       if (siConEvnt->serviceAct2.eh.pres != PRSNT_NODEF) memset(&siConEvnt->serviceAct2, 0, sizeof(siConEvnt->serviceAct2));
+#endif
+       if (siConEvnt->serviceAct2.eh.pres != PRSNT_NODEF) memset(&siConEvnt->serviceAct2, 0, sizeof(siConEvnt->serviceAct2));
+       if (siConEvnt->serviceAct.eh.pres != PRSNT_NODEF) memset(&siConEvnt->serviceAct, 0, sizeof(siConEvnt->serviceAct));
+       if (siConEvnt->mlppPrec.eh.pres != PRSNT_NODEF) memset(&siConEvnt->mlppPrec, 0, sizeof(siConEvnt->mlppPrec));   
+#if (defined(SIT_PARAMETER) || defined(TDS_ROLL_UPGRADE_SUPPORT))
+       if (siConEvnt->txMedUsPr.eh.pres != PRSNT_NODEF) memset(&siConEvnt->txMedUsPr, 0, sizeof(siConEvnt->txMedUsPr));
+#endif
+       if (siConEvnt->bckCallInd.eh.pres != PRSNT_NODEF) memset(&siConEvnt->bckCallInd, 0, sizeof(siConEvnt->bckCallInd));
+       if (siConEvnt->cgPtyNum1.eh.pres != PRSNT_NODEF) memset(&siConEvnt->cgPtyNum1, 0, sizeof(siConEvnt->cgPtyNum1));
+       if (siConEvnt->optBckCalInd.eh.pres != PRSNT_NODEF) memset(&siConEvnt->optBckCalInd, 0, sizeof(siConEvnt->optBckCalInd));
+#if (SS7_Q767 || SS7_RUSSIA || SS7_NTT)
+       if (siConEvnt->optBckCalIndQ.eh.pres != PRSNT_NODEF) memset(&siConEvnt->optBckCalIndQ, 0, sizeof(siConEvnt->optBckCalIndQ));
+#endif
+       if (siConEvnt->connNum.eh.pres != PRSNT_NODEF) memset(&siConEvnt->connNum, 0, sizeof(siConEvnt->connNum));
+#if (defined(SIT_PARAMETER) || defined(TDS_ROLL_UPGRADE_SUPPORT))
+       if (siConEvnt->connNum2.eh.pres != PRSNT_NODEF) memset(&siConEvnt->connNum2, 0, sizeof(siConEvnt->connNum2));
+#endif
+       if (siConEvnt->accDelInfo.eh.pres != PRSNT_NODEF) memset(&siConEvnt->accDelInfo, 0, sizeof(siConEvnt->accDelInfo));
+       if (siConEvnt->notifInd.eh.pres != PRSNT_NODEF) memset(&siConEvnt->notifInd, 0, sizeof(siConEvnt->notifInd));
+       if (siConEvnt->notifIndR2.eh.pres != PRSNT_NODEF) memset(&siConEvnt->notifIndR2, 0, sizeof(siConEvnt->notifIndR2));
+       if (siConEvnt->cllHstry.eh.pres != PRSNT_NODEF) memset(&siConEvnt->cllHstry, 0, sizeof(siConEvnt->cllHstry));
+       if (siConEvnt->genNmb.eh.pres != PRSNT_NODEF) memset(&siConEvnt->genNmb, 0, sizeof(siConEvnt->genNmb));
+       if (siConEvnt->genNmbR.eh.pres != PRSNT_NODEF) memset(&siConEvnt->genNmbR, 0, sizeof(siConEvnt->genNmbR));
+       if (siConEvnt->redirNum.eh.pres != PRSNT_NODEF) memset(&siConEvnt->redirNum, 0, sizeof(siConEvnt->redirNum));
+       if (siConEvnt->redirRstr.eh.pres != PRSNT_NODEF) memset(&siConEvnt->redirRstr, 0, sizeof(siConEvnt->redirRstr));
+
+#if SS7_Q767IT
+       if (siConEvnt->backVad.eh.pres != PRSNT_NODEF) memset(&siConEvnt->backVad, 0, sizeof(siConEvnt->backVad));
+#endif
+#if SS7_SINGTEL
+       if (siConEvnt->cgPtyNumS.eh.pres != PRSNT_NODEF) memset(&siConEvnt->cgPtyNumS, 0, sizeof(siConEvnt->cgPtyNumS));
+#endif
+#if (SS7_ANS92 || SS7_ANS95 || SS7_BELL)
+       if (siConEvnt->businessGrp.eh.pres != PRSNT_NODEF) memset(&siConEvnt->businessGrp, 0, sizeof(siConEvnt->businessGrp));
+       if (siConEvnt->infoInd.eh.pres != PRSNT_NODEF) memset(&siConEvnt->infoInd, 0, sizeof(siConEvnt->infoInd));
+       if (siConEvnt->carrierId.eh.pres != PRSNT_NODEF) memset(&siConEvnt->carrierId, 0, sizeof(siConEvnt->carrierId));
+       if (siConEvnt->carSelInf.eh.pres != PRSNT_NODEF) memset(&siConEvnt->carSelInf, 0, sizeof(siConEvnt->carSelInf));
+       if (siConEvnt->egress.eh.pres != PRSNT_NODEF) memset(&siConEvnt->egress, 0, sizeof(siConEvnt->egress));
+       if (siConEvnt->genAddr.eh.pres != PRSNT_NODEF) memset(&siConEvnt->genAddr, 0, sizeof(siConEvnt->genAddr));
+       if (siConEvnt->genAddrR.eh.pres != PRSNT_NODEF) memset(&siConEvnt->genAddrR, 0, sizeof(siConEvnt->genAddrR));
+       if (siConEvnt->infoReqInd.eh.pres != PRSNT_NODEF) memset(&siConEvnt->infoReqInd, 0, sizeof(siConEvnt->infoReqInd));
+       if (siConEvnt->jurisInf.eh.pres != PRSNT_NODEF) memset(&siConEvnt->jurisInf, 0, sizeof(siConEvnt->jurisInf));
+       if (siConEvnt->netTransport.eh.pres != PRSNT_NODEF) memset(&siConEvnt->netTransport, 0, sizeof(siConEvnt->netTransport));
+       if (siConEvnt->specProcReq.eh.pres != PRSNT_NODEF) memset(&siConEvnt->specProcReq, 0, sizeof(siConEvnt->specProcReq));
+       if (siConEvnt->transReq.eh.pres != PRSNT_NODEF) memset(&siConEvnt->transReq, 0, sizeof(siConEvnt->transReq));
+#endif
+#if (defined(SIT_PARAMETER) || defined(TDS_ROLL_UPGRADE_SUPPORT))
+#if (SS7_ANS92 || SS7_ANS95)
+       if (siConEvnt->notifInd1.eh.pres != PRSNT_NODEF) memset(&siConEvnt->notifInd1, 0, sizeof(siConEvnt->notifInd1));
+       if (siConEvnt->notifIndR1.eh.pres != PRSNT_NODEF) memset(&siConEvnt->notifIndR1, 0, sizeof(siConEvnt->notifIndR1));
+#endif /* SS7_ANS92 */
+#endif /* SIT_PARAMETER || TDS_ROLL_UPGRADE_SUPPORT */
+#if (SS7_BELL || SS7_ANS95)
+       if (siConEvnt->genName.eh.pres != PRSNT_NODEF) memset(&siConEvnt->genName, 0, sizeof(siConEvnt->genName));
+#endif
+#if (SS7_ITU97 || SS7_RUSS2000 || SS7_ITU2000 || SS7_ETSIV3 || \
+       SS7_BELL || SS7_ANS95 || SS7_INDIA || SS7_UK || SS7_NZL || SS7_KZ)
+       if (siConEvnt->hopCounter.eh.pres != PRSNT_NODEF) memset(&siConEvnt->hopCounter, 0, sizeof(siConEvnt->hopCounter));
+#endif
+#if (SS7_BELL || SS7_ITU2000 || SS7_KZ)
+       if (siConEvnt->redirCap.eh.pres != PRSNT_NODEF) memset(&siConEvnt->redirCap, 0, sizeof(siConEvnt->redirCap));
+       if (siConEvnt->redirCntr.eh.pres != PRSNT_NODEF) memset(&siConEvnt->redirCntr, 0, sizeof(siConEvnt->redirCntr));
+#endif
+#if (SS7_ETSI || SS7_FTZ)
+       if (siConEvnt->ccbsParam.eh.pres != PRSNT_NODEF) memset(&siConEvnt->ccbsParam, 0, sizeof(siConEvnt->ccbsParam));
+       if (siConEvnt->freePhParam.eh.pres != PRSNT_NODEF) memset(&siConEvnt->freePhParam, 0, sizeof(siConEvnt->freePhParam));
+#endif
+#ifdef SS7_FTZ
+       if (siConEvnt->naPaFF.eh.pres != PRSNT_NODEF) memset(&siConEvnt->naPaFF, 0, sizeof(siConEvnt->naPaFF));
+       if (siConEvnt->naPaFE.eh.pres != PRSNT_NODEF) memset(&siConEvnt->naPaFE, 0, sizeof(siConEvnt->naPaFE));
+       if (siConEvnt->naPaSSP.eh.pres != PRSNT_NODEF) memset(&siConEvnt->naPaSSP, 0, sizeof(siConEvnt->naPaSSP));
+       if (siConEvnt->naPaCdPNO.eh.pres != PRSNT_NODEF) memset(&siConEvnt->naPaCdPNO, 0, sizeof(siConEvnt->naPaCdPNO));
+       if (siConEvnt->naPaSPV.eh.pres != PRSNT_NODEF) memset(&siConEvnt->naPaSPV, 0, sizeof(siConEvnt->naPaSPV));
+       if (siConEvnt->naPaUKK.eh.pres != PRSNT_NODEF) memset(&siConEvnt->naPaUKK, 0, sizeof(siConEvnt->naPaUKK));
+#endif
+#if SS7_NTT
+       if (siConEvnt->msgAreaInfo.eh.pres != PRSNT_NODEF) memset(&siConEvnt->msgAreaInfo, 0, sizeof(siConEvnt->msgAreaInfo));
+       if (siConEvnt->subsNumber.eh.pres != PRSNT_NODEF) memset(&siConEvnt->subsNumber, 0, sizeof(siConEvnt->subsNumber));
+       if (siConEvnt->rpCllngNo.eh.pres != PRSNT_NODEF) memset(&siConEvnt->rpCllngNo, 0, sizeof(siConEvnt->rpCllngNo));
+       if (siConEvnt->supplUserType.eh.pres != PRSNT_NODEF) memset(&siConEvnt->supplUserType, 0, sizeof(siConEvnt->supplUserType));
+       if (siConEvnt->carrierInfoTrans.eh.pres != PRSNT_NODEF) memset(&siConEvnt->carrierInfoTrans, 0, sizeof(siConEvnt->carrierInfoTrans));
+       if (siConEvnt->nwFuncType.eh.pres != PRSNT_NODEF) memset(&siConEvnt->nwFuncType, 0, sizeof(siConEvnt->nwFuncType));
+#endif
+#if SS7_ANS95
+       if (siConEvnt->optrServicesInfo.eh.pres != PRSNT_NODEF) memset(&siConEvnt->optrServicesInfo, 0, sizeof(siConEvnt->optrServicesInfo));
+#endif
+#if (SS7_ANS95 || SS7_ITU97  || SS7_RUSS2000|| SS7_ITU2000 || SS7_NZL || SS7_KZ)
+       if (siConEvnt->cirAsgnMap.eh.pres != PRSNT_NODEF) memset(&siConEvnt->cirAsgnMap, 0, sizeof(siConEvnt->cirAsgnMap));
+#endif
+#if (SS7_ITU97 || SS7_RUSS2000 || SS7_ITU2000 || SS7_ETSIV3 || \
+       SS7_INDIA || SS7_UK || SS7_NZL || SS7_KZ)
+       if (siConEvnt->displayInfo.eh.pres != PRSNT_NODEF) memset(&siConEvnt->displayInfo, 0, sizeof(siConEvnt->displayInfo));
+       if (siConEvnt->confTrtInd.eh.pres != PRSNT_NODEF) memset(&siConEvnt->confTrtInd, 0, sizeof(siConEvnt->confTrtInd));
+       if (siConEvnt->netMgmtControls.eh.pres != PRSNT_NODEF) memset(&siConEvnt->netMgmtControls, 0, sizeof(siConEvnt->netMgmtControls));
+       if (siConEvnt->correlationId.eh.pres != PRSNT_NODEF) memset(&siConEvnt->correlationId, 0, sizeof(siConEvnt->correlationId));
+       if (siConEvnt->callDivTrtInd.eh.pres != PRSNT_NODEF) memset(&siConEvnt->callDivTrtInd, 0, sizeof(siConEvnt->callDivTrtInd));
+       if (siConEvnt->callInNmb.eh.pres != PRSNT_NODEF) memset(&siConEvnt->callInNmb, 0, sizeof(siConEvnt->callInNmb));
+       if (siConEvnt->callOfferTrtInd.eh.pres != PRSNT_NODEF) memset(&siConEvnt->callOfferTrtInd, 0, sizeof(siConEvnt->callOfferTrtInd));
+       if (siConEvnt->scfId.eh.pres != PRSNT_NODEF) memset(&siConEvnt->scfId, 0, sizeof(siConEvnt->scfId));
+       if (siConEvnt->uidCapInd.eh.pres != PRSNT_NODEF) memset(&siConEvnt->uidCapInd, 0, sizeof(siConEvnt->uidCapInd));
+       if (siConEvnt->collCallReq.eh.pres != PRSNT_NODEF) memset(&siConEvnt->collCallReq, 0, sizeof(siConEvnt->collCallReq));
+       if (siConEvnt->ccss.eh.pres != PRSNT_NODEF) memset(&siConEvnt->ccss, 0, sizeof(siConEvnt->ccss));
+#endif
+#if (SS7_ITU97 || SS7_RUSS2000 || SS7_ITU2000 || SS7_UK || SS7_NZL || SS7_KZ)
+       if (siConEvnt->backGVNS.eh.pres != PRSNT_NODEF) memset(&siConEvnt->backGVNS, 0, sizeof(siConEvnt->backGVNS));
+       if (siConEvnt->forwardGVNS.eh.pres != PRSNT_NODEF) memset(&siConEvnt->forwardGVNS, 0, sizeof(siConEvnt->forwardGVNS));
+#endif
+#if (SS7_ETSIV3 || SS7_ITU97 || SS7_RUSS2000 || SS7_ITU2000 || \
+       SS7_INDIA || SS7_UK || SS7_NZL || SS7_KZ)
+       if (siConEvnt->appTransParam.eh.pres != PRSNT_NODEF) memset(&siConEvnt->appTransParam, 0, sizeof(siConEvnt->appTransParam));
+#endif
+#if (SS7_ITU2000 || SS7_UK || SS7_NZL || SS7_KZ)
+       if (siConEvnt->htrInfo.eh.pres != PRSNT_NODEF) memset(&siConEvnt->htrInfo, 0, sizeof(siConEvnt->htrInfo));
+       if (siConEvnt->pivotCap.eh.pres != PRSNT_NODEF) memset(&siConEvnt->pivotCap, 0, sizeof(siConEvnt->pivotCap));
+       if (siConEvnt->cadDirNmb.eh.pres != PRSNT_NODEF) memset(&siConEvnt->cadDirNmb, 0, sizeof(siConEvnt->cadDirNmb));
+       if (siConEvnt->origCallInNum.eh.pres != PRSNT_NODEF) memset(&siConEvnt->origCallInNum, 0, sizeof(siConEvnt->origCallInNum));
+       if (siConEvnt->calgGeoLoc.eh.pres != PRSNT_NODEF) memset(&siConEvnt->calgGeoLoc, 0, sizeof(siConEvnt->calgGeoLoc));
+       if (siConEvnt->netRoutNum.eh.pres != PRSNT_NODEF) memset(&siConEvnt->netRoutNum, 0, sizeof(siConEvnt->netRoutNum));
+       if (siConEvnt->qonRelCap.eh.pres != PRSNT_NODEF) memset(&siConEvnt->qonRelCap, 0, sizeof(siConEvnt->qonRelCap));
+       if (siConEvnt->pivotCntr.eh.pres != PRSNT_NODEF) memset(&siConEvnt->pivotCntr, 0, sizeof(siConEvnt->pivotCntr));
+       if (siConEvnt->pivotRtgFwInfo.eh.pres != PRSNT_NODEF) memset(&siConEvnt->pivotRtgFwInfo, 0, sizeof(siConEvnt->pivotRtgFwInfo));
+       if (siConEvnt->pivotRtgBkInfo.eh.pres != PRSNT_NODEF) memset(&siConEvnt->pivotRtgBkInfo, 0, sizeof(siConEvnt->pivotRtgBkInfo));
+       if (siConEvnt->numPortFwdInfo.eh.pres != PRSNT_NODEF) memset(&siConEvnt->numPortFwdInfo, 0, sizeof(siConEvnt->numPortFwdInfo));
+#endif
+#ifdef SS7_UK
+       if (siConEvnt->natFwdCalInd.eh.pres != PRSNT_NODEF) memset(&siConEvnt->natFwdCalInd, 0, sizeof(siConEvnt->natFwdCalInd));
+       if (siConEvnt->presntNum.eh.pres != PRSNT_NODEF) memset(&siConEvnt->presntNum, 0, sizeof(siConEvnt->presntNum));
+       if (siConEvnt->lstDvrtLineId.eh.pres != PRSNT_NODEF) memset(&siConEvnt->lstDvrtLineId, 0, sizeof(siConEvnt->lstDvrtLineId));
+       if (siConEvnt->pcgLineId.eh.pres != PRSNT_NODEF) memset(&siConEvnt->pcgLineId, 0, sizeof(siConEvnt->pcgLineId));
+       if (siConEvnt->natFwdCalIndLnk.eh.pres != PRSNT_NODEF) memset(&siConEvnt->natFwdCalIndLnk, 0, sizeof(siConEvnt->natFwdCalIndLnk));
+       if (siConEvnt->cdBascSrvcMrk.eh.pres != PRSNT_NODEF) memset(&siConEvnt->cdBascSrvcMrk, 0, sizeof(siConEvnt->cdBascSrvcMrk));
+#endif /* SS7_UK */
+#if (defined(CGPN_CHK))
+       if (siConEvnt->causeDgnCgPnChk.eh.pres != PRSNT_NODEF) memset(&siConEvnt->causeDgnCgPnChk, 0, sizeof(siConEvnt->causeDgnCgPnChk));
+#endif
+       return FTDM_SUCCESS;
+}
+
+ftdm_status_t sngss7_save_iam(ftdm_channel_t *ftdmchan, SiConEvnt *siConEvnt)
+{
+#ifndef HAVE_ZLIB
+       ftdm_log_chan_msg(ftdmchan, FTDM_LOG_CRIT, "Cannot perform transparent IAM because zlib is missing\n");
+       return FTDM_FAIL;
+#else
+       unsigned ret_val = FTDM_FAIL;
+       char *compressed_iam = NULL;
+       char *url_encoded_iam = NULL;
+       uLongf len = sizeof(*siConEvnt);        
+       sngss7_chan_data_t      *sngss7_info = ftdmchan->call_data;
+
+       /* By default, Trillium does not memset their whole structure to zero for
+        * performance. But we want to memset all the IE's that are not present to
+        * optimize compressed size */
+       sngss7_bufferzero_iam(siConEvnt);
+       
+       compressed_iam = ftdm_malloc(sizeof(*siConEvnt));
+       if (!compressed_iam) {
+               ftdm_log_chan_msg(ftdmchan, FTDM_LOG_CRIT, "Failed to allocate buffer for compressed_iam\n");
+               goto done;
+       }
+
+       /* Compress IAM structure to minimize buffer size */
+       ret_val = compress((Bytef *)compressed_iam, &len, (const Bytef *)siConEvnt, (uLong)sizeof(*siConEvnt));
+       if (ret_val != Z_OK) {
+               ftdm_log_chan(ftdmchan, FTDM_LOG_CRIT, "Failed to compress IAM (error:%d)\n", ret_val);
+               ret_val = FTDM_FAIL;
+               goto done;
+       }
+
+       ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "Compressed IAM size:%d\n", len);
+
+       /* Worst case: size will triple after url encode */
+       url_encoded_iam = ftdm_malloc(3*sizeof(*siConEvnt));
+       if (!url_encoded_iam) {
+               ftdm_log_chan_msg(ftdmchan, FTDM_LOG_CRIT, "Failed to allocated buffer for url_encoded_iam\n");
+               ret_val = FTDM_FAIL;
+               goto done;
+       }
+       memset(url_encoded_iam, 0, 2*sizeof(*siConEvnt));
+       
+       /* URL encode buffer to that its safe to store it in a string */
+       ftdm_url_encode((const char*)compressed_iam, url_encoded_iam, len);
+
+       ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "IAM variable length:%d\n", strlen(url_encoded_iam));
+
+       if (strlen(url_encoded_iam) > g_ftdm_sngss7_data.cfg.transparent_iam_max_size) {
+               ftdm_log_chan(ftdmchan, FTDM_LOG_CRIT, "IAM variable length exceeds max size (len:%d max:%d) \n", strlen(url_encoded_iam), g_ftdm_sngss7_data.cfg.transparent_iam_max_size);
+               ret_val = FTDM_FAIL;
+               goto done;
+       }
+       
+       sngss7_add_var(sngss7_info, "ss7_iam", url_encoded_iam);
+done:  
+       ftdm_safe_free(compressed_iam);
+       ftdm_safe_free(url_encoded_iam);
+       return ret_val;
+#endif
+}
+
+ftdm_status_t sngss7_retrieve_iam(ftdm_channel_t *ftdmchan, SiConEvnt *siConEvnt)
+{
+#ifndef HAVE_ZLIB
+       ftdm_log_chan_msg(ftdmchan, FTDM_LOG_CRIT, "Cannot perform transparent IAM because zlib is missing\n");
+       return FTDM_FAIL;
+#else  
+       uLongf len = 3*sizeof(*siConEvnt); /* worst case: URL encoded buffer is 3x length of buffer */
+       char *val = NULL;
+       unsigned ret_val = FTDM_FAIL;   
+       void *uncompressed_buffer = NULL;
+       char *url_encoded_iam = NULL;
+       ftdm_size_t url_encoded_iam_len;
+
+       val = (char*)ftdm_usrmsg_get_var(ftdmchan->usrmsg, "ss7_iam");
+       if (ftdm_strlen_zero(val)) {
+               ftdm_log_chan_msg(ftdmchan, FTDM_LOG_DEBUG, "No Transparent IAM info available\n");
+               return FTDM_FAIL;
+       }
+
+       url_encoded_iam = ftdm_strdup(val);
+
+       ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "IAM variable length:%d\n", strlen(val));
+       ftdm_url_decode(url_encoded_iam, &url_encoded_iam_len);
+       
+       ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "Compressed IAM size:%d\n", url_encoded_iam_len);
+
+       uncompressed_buffer = ftdm_malloc(sizeof(*siConEvnt));
+       ftdm_assert_return(uncompressed_buffer, FTDM_FAIL, "Failed to allocate buffer for uncompressed buffer\n");
+
+       ret_val = uncompress(uncompressed_buffer, &len, (const Bytef *)url_encoded_iam, (uLong)url_encoded_iam_len);
+       if (ret_val != Z_OK) {
+               ftdm_log_chan(ftdmchan, FTDM_LOG_CRIT, "Failed to uncompress IAM (error:%d)\n", ret_val);
+               goto done;
+       }
+
+       if (len != sizeof(*siConEvnt)) {
+               ftdm_log_chan(ftdmchan, FTDM_LOG_CRIT, "Incompatible IAM structure size (expected:%d size:%d)\n", sizeof(*siConEvnt), strlen(uncompressed_buffer));
+               goto done;
+       }
+
+       memcpy(siConEvnt, uncompressed_buffer, sizeof(*siConEvnt));
+       ret_val = FTDM_SUCCESS;
+
+done:
+       ftdm_safe_free(uncompressed_buffer);
+       ftdm_safe_free(url_encoded_iam);        
+       return ret_val;
+#endif
+}
+
 /******************************************************************************/
 /* For Emacs:
  * Local Variables:
index 2df0a88edbaa0f7b4ea8d92864adf4e8f972e3af..a891c501082d8e7d1f1d5ab9137bfe72d707e372 100644 (file)
@@ -124,7 +124,8 @@ typedef struct sng_ccSpan
        uint32_t                cld_nadi;
        uint32_t                rdnis_nadi;
        uint32_t                min_digits;
-       uint32_t                itx_auto_reply;
+       uint8_t                 itx_auto_reply;
+       uint8_t                 transparent_iam;
        uint32_t                t3;
        uint32_t                t12;
        uint32_t                t13;
@@ -466,6 +467,9 @@ static int ftmod_ss7_parse_sng_gen(ftdm_conf_node_t *sng_gen)
                        SS7_DEBUG("Found license file = %s\n", g_ftdm_sngss7_data.cfg.license);
                        SS7_DEBUG("Found signature file = %s\n", g_ftdm_sngss7_data.cfg.signature);     
                /**********************************************************************/
+               } else if (!strcasecmp(parm->var, "transparent_iam_max_size")) {
+                       g_ftdm_sngss7_data.cfg.transparent_iam_max_size = atoi(parm->val);
+                       SS7_DEBUG("Found a transparent_iam max size = %d\n", g_ftdm_sngss7_data.cfg.transparent_iam_max_size);
                } else {
                /**********************************************************************/
                        SS7_ERROR("Found an invalid parameter \"%s\"!\n", parm->val);
@@ -1896,6 +1900,13 @@ static int ftmod_ss7_parse_cc_span(ftdm_conf_node_t *cc_span)
                } else if (!strcasecmp(parm->var, "itx_auto_reply")) {
                        sng_ccSpan.itx_auto_reply = ftdm_true(parm->val);
                        SS7_DEBUG("Found itx_auto_reply %d\n", sng_ccSpan.itx_auto_reply);
+               } else if (!strcasecmp(parm->var, "transparent_iam")) {
+#ifndef HAVE_ZLIB
+                       SS7_CRIT("Cannot enable transparent IAM becauze zlib not installed\n");
+#else
+                       sng_ccSpan.transparent_iam = ftdm_true(parm->val);
+                       SS7_DEBUG("Found transparent_iam %d\n", sng_ccSpan.transparent_iam);
+#endif
                } else if (!strcasecmp(parm->var, "cicbase")) {
                /**********************************************************************/
                        sng_ccSpan.cicbase = atoi(parm->val);
@@ -2907,16 +2918,17 @@ static int ftmod_ss7_fill_in_ccSpan(sng_ccSpan_t *ccSpan)
                        g_ftdm_sngss7_data.cfg.isupCkt[x].cic           = 0;
                }
 
-               g_ftdm_sngss7_data.cfg.isupCkt[x].infId                 = ccSpan->isupInf;
-               g_ftdm_sngss7_data.cfg.isupCkt[x].typeCntrl     = ccSpan->typeCntrl;
-               g_ftdm_sngss7_data.cfg.isupCkt[x].ssf                   = ccSpan->ssf;
-               g_ftdm_sngss7_data.cfg.isupCkt[x].cld_nadi              = ccSpan->cld_nadi;
-               g_ftdm_sngss7_data.cfg.isupCkt[x].clg_nadi              = ccSpan->clg_nadi;
-               g_ftdm_sngss7_data.cfg.isupCkt[x].rdnis_nadi    = ccSpan->rdnis_nadi;
-               g_ftdm_sngss7_data.cfg.isupCkt[x].options               = ccSpan->options;
-               g_ftdm_sngss7_data.cfg.isupCkt[x].switchType    = ccSpan->switchType;
-               g_ftdm_sngss7_data.cfg.isupCkt[x].min_digits    = ccSpan->min_digits;
-               g_ftdm_sngss7_data.cfg.isupCkt[x].itx_auto_reply        = ccSpan->itx_auto_reply;
+               g_ftdm_sngss7_data.cfg.isupCkt[x].infId                                         = ccSpan->isupInf;
+               g_ftdm_sngss7_data.cfg.isupCkt[x].typeCntrl                                     = ccSpan->typeCntrl;
+               g_ftdm_sngss7_data.cfg.isupCkt[x].ssf                                           = ccSpan->ssf;
+               g_ftdm_sngss7_data.cfg.isupCkt[x].cld_nadi                                      = ccSpan->cld_nadi;
+               g_ftdm_sngss7_data.cfg.isupCkt[x].clg_nadi                                      = ccSpan->clg_nadi;
+               g_ftdm_sngss7_data.cfg.isupCkt[x].rdnis_nadi                            = ccSpan->rdnis_nadi;
+               g_ftdm_sngss7_data.cfg.isupCkt[x].options                                       = ccSpan->options;
+               g_ftdm_sngss7_data.cfg.isupCkt[x].switchType                            = ccSpan->switchType;
+               g_ftdm_sngss7_data.cfg.isupCkt[x].min_digits                            = ccSpan->min_digits;
+               g_ftdm_sngss7_data.cfg.isupCkt[x].itx_auto_reply                        = ccSpan->itx_auto_reply;
+               g_ftdm_sngss7_data.cfg.isupCkt[x].transparent_iam                       = ccSpan->transparent_iam;
 
                if (ccSpan->t3 == 0) {
                        g_ftdm_sngss7_data.cfg.isupCkt[x].t3                    = 1200;
index 6b14d14524a7b28366e0fd477b1726db71dd9177..1d27b946e3b16419659b77ab6ad678def054447b 100755 (executable)
@@ -276,12 +276,16 @@ FTDM_STR2ENUM_P(ftdm_str2ftdm_screening, ftdm_screening2str, ftdm_screening_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_SPEECH = 0x00,  /* Speech */
+       FTDM_BEARER_CAP_UNRESTRICTED,   /* Unrestricted Digital */
+       FTDM_BEARER_CAP_RESTRICTED,     /* Restricted Digital */
+       FTDM_BEARER_CAP_3_1KHZ_AUDIO,   /* 3.1 Khz Audio */
+       FTDM_BEARER_CAP_7KHZ_AUDIO,     /* 7 Khz Audio or Unrestricted digital w tones */
+       FTDM_BEARER_CAP_15KHZ_AUDIO,    /* 15 Khz Audio */
+       FTDM_BEARER_CAP_VIDEO,          /* Video */
        FTDM_BEARER_CAP_INVALID
 } ftdm_bearer_cap_t;
-#define BEARER_CAP_STRINGS "speech", "unrestricted-digital-information", "3.1-Khz-audio", "invalid"
+#define BEARER_CAP_STRINGS "speech", "unrestricted-digital-information", "restricted-digital-information", "3.1-Khz-audio", "7-Khz-audio", "15-Khz-audio", "video", "invalid"
 FTDM_STR2ENUM_P(ftdm_str2ftdm_bearer_cap, ftdm_bearer_cap2str, ftdm_bearer_cap_t)
 
 /*! \brief user information layer 1 protocol */
index 2418273343f283cf361f347bc6cd40edda31c52d..975e73e72947560cb76fb1a1ba82dceed4a75d39 100644 (file)
@@ -131,5 +131,24 @@ FT_DECLARE(ftdm_status_t) ftdm_is_number(const char *number);
  */
 FT_DECLARE(ftdm_status_t) ftdm_set_calling_party_category(const char *string, uint8_t *target);
 
+/*! 
+ * \brief URL encode a buffer
+ *
+ * \param url buffer to convert
+ * \param buf target to save converted string to
+ * \param len size of buffer
+ *
+ * \retval pointer to converted string
+ */
+FT_DECLARE(char *) ftdm_url_encode(const char *url, char *buf, ftdm_size_t len);
+
+/*! 
+ * \param s buffer to convert
+ * \param len size of buffer
+ *     
+ * \retval pointer to converted string
+ */
+FT_DECLARE(char *) ftdm_url_decode(char *s, ftdm_size_t *len);
+
 #endif /* __FTDM_CALL_UTILS_H__ */