ss7: add ss7_iam_nature_connection_hex to support Nature of Connection

Indicator in IAM message.
     - ss7_iam_nature_connection_hex is the channel variable to carry
       HEX value from/to IAM message
     - X-FreeTDM-IAM-NATURE-CONN-HEX is the x-header string to carry
       HEX value from/to sip invite message
     - This IE is 8 bit hex, which turns into 2 chars
     - Only Satellite indicator, Continuity check indicator, and Echo
       control device indicator are supported. Spare value are not taken.
       Spare value is always set to all zero.
     - example:
       To set 00010101 (bit H-A), set X-FreeTDM-IAM-NATURE-CONN-HEX string
       value to 15 in the sip invite message to NSG.
       When NSG send out sip invite, if the incoming IAM message comes with
       Nature of Connection IE, NSG will put X-FreeTDM-IAM-NATURE-CONN-HEX
       in the invite x-header. For example, if the IE value is 00001010 in
       the IAM, NSG will send X-FreeTDM-IAM-NATURE-CONN-HEX with value string
       of "0A".
     - Two characters are madatory. "0A" must be specified rather than "A". If
       invalid format or characters are found, this x-header will be ommited.
     - Valid characters include 0-9, A-F, and a-f
This commit is contained in:
James Zhang 2012-06-27 12:31:35 -04:00
parent 607da0f56c
commit 80f72823b3
5 changed files with 148 additions and 0 deletions

View File

@ -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);

View File

@ -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);

View File

@ -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);

View File

@ -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,

View File

@ -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];