diff --git a/libs/freetdm/mod_freetdm/mod_freetdm.c b/libs/freetdm/mod_freetdm/mod_freetdm.c index ed57b8c0c3..a3e9fd4568 100755 --- a/libs/freetdm/mod_freetdm/mod_freetdm.c +++ b/libs/freetdm/mod_freetdm/mod_freetdm.c @@ -1558,6 +1558,11 @@ static switch_call_cause_t channel_outgoing_channel(switch_core_session_t *sessi if (sipvar) { ftdm_usrmsg_add_var(&usrmsg, "ss7_iam_fwd_ind_hex", sipvar); } + + sipvar = switch_channel_get_variable(channel, "sip_h_X-FreeTDM-IAM-NATURE-CONN-HEX"); + if (sipvar) { + ftdm_usrmsg_add_var(&usrmsg, "ss7_iam_nature_connection_hex", sipvar); + } } if (switch_test_flag(outbound_profile, SWITCH_CPF_SCREEN)) { @@ -1873,7 +1878,13 @@ 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-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_iam_nature_connection_hex"); + if (!ftdm_strlen_zero(var_value)) { + switch_channel_set_variable_printf(channel, "sip_h_X-FreeTDM-IAM-NATURE-CONN-HEX", "%s", var_value); + } + var_value = ftdm_sigmsg_get_var(sigmsg, "ss7_iam_fwd_ind_hex"); if (!ftdm_strlen_zero(var_value)) { switch_channel_set_variable_printf(channel, "sip_h_X-FreeTDM-IAM-FWD-IND-HEX", "%s", var_value); 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 beacecc180..a4802b1853 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 @@ -221,6 +221,7 @@ ftdm_status_t handle_con_ind(uint32_t suInstId, uint32_t spInstId, uint32_t circ } else { SS7_INFO_CHAN(ftdmchan,"No Called party (DNIS) information in IAM!%s\n", " "); } + copy_NatureOfConnection_from_sngss7(ftdmchan, &siConEvnt->natConInd); copy_fwdCallInd_hex_from_sngss7(ftdmchan, &siConEvnt->fwdCallInd); copy_access_transport_from_sngss7(ftdmchan, &siConEvnt->accTrnspt); copy_ocn_from_sngss7(ftdmchan, &siConEvnt->origCdNum); 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 3b62f67850..1e064f2522 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 @@ -930,6 +930,8 @@ ftdm_status_t copy_fwdCallInd_hex_from_sngss7(ftdm_channel_t *ftdmchan, SiFwdCal 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_NatureOfConnection_from_sngss7(ftdm_channel_t *ftdmchan, SiNatConInd *natConInd ); +ftdm_status_t copy_NatureOfConnection_to_sngss7(ftdm_channel_t *ftdmchan, SiNatConInd *natConInd); 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); 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 bf693c0999..4f177a3957 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 @@ -163,6 +163,8 @@ void ft_to_sngss7_iam (ftdm_channel_t * ftdmchan) copy_ocn_to_sngss7(ftdmchan, &iam.origCdNum); copy_access_transport_to_sngss7(ftdmchan, &iam.accTrnspt); + + copy_NatureOfConnection_to_sngss7(ftdmchan, &iam.natConInd); } else { /* Nature of Connection Indicators */ copy_natConInd_to_sngss7(ftdmchan, &iam.natConInd); @@ -209,6 +211,8 @@ void ft_to_sngss7_iam (ftdm_channel_t * ftdmchan) This will overwirte the IE value set be above old implementation. */ copy_access_transport_to_sngss7(ftdmchan, &iam.accTrnspt); + + copy_NatureOfConnection_to_sngss7(ftdmchan, &iam.natConInd); SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Tx IAM clg = \"%s\" (NADI=%d), cld = \"%s\" (NADI=%d), loc = %s (NADI=%d)\n", sngss7_info->circuit->cic, diff --git a/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_support.c b/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_support.c index bafd2d3f8d..2f4c18d4c3 100644 --- a/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_support.c +++ b/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_support.c @@ -90,6 +90,10 @@ static uint8_t get_ftdm_val(ftdm2trillium_t *vals, uint8_t trillium_val, uint8_t ftdm_status_t four_char_to_hex(const char* in, uint16_t* out) ; ftdm_status_t hex_to_four_char(uint16_t in, char* out); + +ftdm_status_t hex_to_char(uint16_t in, char* out, int len); +ftdm_status_t char_to_hex(const char* in, uint16_t* out, int len); + /* Maps generic FreeTDM CPC codes to SS7 CPC codes */ ftdm2trillium_t cpc_codes[] = { {FTDM_CPC_UNKNOWN, CAT_UNKNOWN}, @@ -976,7 +980,79 @@ ftdm_status_t four_char_to_hex(const char* in, uint16_t* out) return FTDM_SUCCESS; } +ftdm_status_t char_to_hex(const char* in, uint16_t* out, int len) +{ + int i= len; + char *val = ftdm_malloc(len*sizeof(char)); + + if (!val ||!in || len>strlen(in)) { + return FTDM_FAIL; + } + + while(i) + { + switch((char)*(in+(len-i))) { + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': + *(val+(len-i)) = *(in+(len-i)) - 48; + break; + case 'A': + case 'B': + case 'C': + case 'D': + case 'E': + case 'F': + *(val+(len-i)) = *(in+(len-i)) - 55; + break; + case 'a': + case 'b': + case 'c': + case 'd': + case 'e': + case 'f': + *(val+(len-i)) = *(in+(len-i)) - 87; + break; + default: + SS7_ERROR("Invalid character found when decoding hex string, %c!\n", *(in+(len-i)) ); + break; + } + i--; + }; + for (i=0; i<=len-1; i++) { + *out = *out << 4; + *out |= *(val+i); + } + + return FTDM_SUCCESS; +} + + + +ftdm_status_t hex_to_char(uint16_t in, char* out, int len) +{ + char val=0; + int mask = 0xf; + int i=0; + if (!out) { + return FTDM_SUCCESS; + } + + for (i=len-1; i>=0; i--) { + val = (in & (mask<<(4*i))) >> (4*i); + sprintf (out+(len-1-i), "%x", val); + } + + return FTDM_SUCCESS; +} ftdm_status_t hex_to_four_char(uint16_t in, char* out) { char val=0; @@ -994,6 +1070,60 @@ ftdm_status_t hex_to_four_char(uint16_t in, char* out) return FTDM_SUCCESS; } +ftdm_status_t copy_NatureOfConnection_to_sngss7(ftdm_channel_t *ftdmchan, SiNatConInd *natConInd) +{ + const char *val = NULL; + + natConInd->eh.pres = PRSNT_NODEF; + natConInd->satInd.pres = PRSNT_NODEF; + natConInd->contChkInd.pres = PRSNT_NODEF;; + natConInd->echoCntrlDevInd.pres = PRSNT_NODEF; + + val = ftdm_usrmsg_get_var(ftdmchan->usrmsg, "ss7_iam_nature_connection_hex"); + if (!ftdm_strlen_zero(val)) { + uint16_t val_hex = 0; + if (char_to_hex (val, &val_hex, 2) == FTDM_FAIL) { + SS7_ERROR ("Wrong value set in ss7_iam_nature_connection_hex variable. Please correct the error. Setting to default values.\n" ); + } else { + ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "hex = 0x%x\n", val_hex); + natConInd->satInd.val = (val_hex & 0x3); + natConInd->contChkInd.val = (val_hex & 0xc)>>2; + natConInd->echoCntrlDevInd.val = (val_hex & 0x10) >> 4; + + return FTDM_SUCCESS; + } + } + + natConInd->satInd.val = 0; + natConInd->contChkInd.val = 0; + natConInd->echoCntrlDevInd.val = 0; + + return FTDM_SUCCESS; +} + +ftdm_status_t copy_NatureOfConnection_from_sngss7(ftdm_channel_t *ftdmchan, SiNatConInd *natConInd ) +{ + char val[3]; + uint16_t val_hex = 0; + sngss7_chan_data_t *sngss7_info = ftdmchan->call_data; + + memset (val, 0, 3*sizeof(char)); + if (natConInd->eh.pres != PRSNT_NODEF ) { + ftdm_log_chan_msg(ftdmchan, FTDM_LOG_DEBUG, "No nature of connection indicator IE available\n"); + return FTDM_SUCCESS; + } + + val_hex |= natConInd->satInd.val; + val_hex |= natConInd->contChkInd.val << 2; + val_hex |= natConInd->echoCntrlDevInd.val <<4; + hex_to_char(val_hex, val, 2) ; + + sngss7_add_var(sngss7_info, "ss7_iam_nature_connection_hex", val); + ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "Nature of connection indicator Hex: 0x%s\n", val); + + return FTDM_SUCCESS; +} + ftdm_status_t copy_fwdCallInd_hex_from_sngss7(ftdm_channel_t *ftdmchan, SiFwdCallInd *fwdCallInd) { char val[5];