freetdm - ISDN support for sending Network Specific Facility
This commit is contained in:
parent
2453a4e709
commit
44ed952a7b
|
@ -499,6 +499,7 @@ ftdm_status_t get_calling_subaddr(ftdm_channel_t *ftdmchan, CgPtySad *cgPtySad);
|
|||
ftdm_status_t get_prog_ind_ie(ftdm_channel_t *ftdmchan, ProgInd *progInd);
|
||||
ftdm_status_t get_facility_ie(ftdm_channel_t *ftdmchan, FacilityStr *facilityStr);
|
||||
ftdm_status_t get_facility_ie_str(ftdm_channel_t *ftdmchan, uint8_t *data, uint8_t data_len);
|
||||
ftdm_status_t get_network_specific_fac(ftdm_channel_t *ftdmchan, NetFac *netFac);
|
||||
|
||||
ftdm_status_t set_calling_num(ftdm_channel_t *ftdmchan, CgPtyNmb *cgPtyNmb);
|
||||
ftdm_status_t set_calling_num2(ftdm_channel_t *ftdmchan, CgPtyNmb *cgPtyNmb);
|
||||
|
@ -508,6 +509,7 @@ ftdm_status_t set_calling_name(ftdm_channel_t *ftdmchan, ConEvnt *conEvnt);
|
|||
ftdm_status_t set_calling_subaddr(ftdm_channel_t *ftdmchan, CgPtySad *cgPtySad);
|
||||
ftdm_status_t set_prog_ind_ie(ftdm_channel_t *ftdmchan, ProgInd *progInd, ftdm_sngisdn_progind_t prog_ind);
|
||||
ftdm_status_t set_bear_cap_ie(ftdm_channel_t *ftdmchan, BearCap *bearCap);
|
||||
ftdm_status_t set_network_specific_fac(ftdm_channel_t *ftdmchan, NetFac *netFac);
|
||||
ftdm_status_t set_chan_id_ie(ftdm_channel_t *ftdmchan, ChanId *chanId);
|
||||
ftdm_status_t set_restart_ind_ie(ftdm_channel_t *ftdmchan, RstInd *rstInd);
|
||||
ftdm_status_t set_facility_ie(ftdm_channel_t *ftdmchan, FacilityStr *facilityStr);
|
||||
|
|
|
@ -133,8 +133,9 @@ void sngisdn_process_con_ind (sngisdn_event_data_t *sngisdn_event)
|
|||
get_redir_num(ftdmchan, &conEvnt->redirNmb);
|
||||
get_calling_subaddr(ftdmchan, &conEvnt->cgPtySad);
|
||||
get_prog_ind_ie(ftdmchan, &conEvnt->progInd);
|
||||
get_facility_ie(ftdmchan, &conEvnt->facilityStr);
|
||||
get_facility_ie(ftdmchan, &conEvnt->facilityStr);
|
||||
get_calling_name(ftdmchan, conEvnt);
|
||||
get_network_specific_fac(ftdmchan, &conEvnt->netFac[0]);
|
||||
|
||||
ftdm_log_chan(sngisdn_info->ftdmchan, FTDM_LOG_INFO, "Incoming call: Called No:[%s] Calling No:[%s]\n", ftdmchan->caller_data.dnis.digits, ftdmchan->caller_data.cid_num.digits);
|
||||
|
||||
|
|
|
@ -69,6 +69,7 @@ void sngisdn_snd_setup(ftdm_channel_t *ftdmchan)
|
|||
set_calling_subaddr(ftdmchan, &conEvnt.cgPtySad);
|
||||
set_redir_num(ftdmchan, &conEvnt.redirNmb);
|
||||
set_calling_name(ftdmchan, &conEvnt);
|
||||
set_network_specific_fac(ftdmchan, &conEvnt.netFac[0]);
|
||||
|
||||
/* set_facility_ie will overwrite Calling Name for NI-2 if user specifies custom Facility IE */
|
||||
set_facility_ie(ftdmchan, &conEvnt.facilityStr);
|
||||
|
|
|
@ -43,6 +43,15 @@ SNGISDN_STR2ENUM(ftdm_str2ftdm_sngisdn_progind_descr, ftdm_sngisdn_progind_descr
|
|||
SNGISDN_ENUM_NAMES(SNGISDN_PROGIND_LOC_NAMES, SNGISDN_PROGIND_LOC_STRINGS)
|
||||
SNGISDN_STR2ENUM(ftdm_str2ftdm_sngisdn_progind_loc, ftdm_sngisdn_progind_loc2str, ftdm_sngisdn_progind_loc_t, SNGISDN_PROGIND_LOC_NAMES, SNGISDN_PROGIND_LOC_INVALID)
|
||||
|
||||
SNGISDN_ENUM_NAMES(SNGISDN_NETSPECFAC_TYPE_NAMES, SNGISDN_NETSPECFAC_TYPE_STRINGS)
|
||||
SNGISDN_STR2ENUM(ftdm_str2ftdm_sngisdn_netspecfac_type, ftdm_sngisdn_netspecfac_type2str, ftdm_sngisdn_netspecfac_type_t, SNGISDN_NETSPECFAC_TYPE_NAMES, SNGISDN_NETSPECFAC_TYPE_INVALID)
|
||||
|
||||
SNGISDN_ENUM_NAMES(SNGISDN_NETSPECFAC_PLAN_NAMES, SNGISDN_NETSPECFAC_PLAN_STRINGS)
|
||||
SNGISDN_STR2ENUM(ftdm_str2ftdm_sngisdn_netspecfac_plan, ftdm_sngisdn_netspecfac_plan2str, ftdm_sngisdn_netspecfac_plan_t, SNGISDN_NETSPECFAC_PLAN_NAMES, SNGISDN_NETSPECFAC_PLAN_INVALID)
|
||||
|
||||
SNGISDN_ENUM_NAMES(SNGISDN_NETSPECFAC_SPEC_NAMES, SNGISDN_NETSPECFAC_SPEC_STRINGS)
|
||||
SNGISDN_STR2ENUM(ftdm_str2ftdm_sngisdn_netspecfac_spec, ftdm_sngisdn_netspecfac_spec2str, ftdm_sngisdn_netspecfac_spec_t, SNGISDN_NETSPECFAC_SPEC_NAMES, SNGISDN_NETSPECFAC_SPEC_INVALID)
|
||||
|
||||
static uint8_t get_trillium_val(ftdm2trillium_t *vals, uint8_t ftdm_val, uint8_t default_val);
|
||||
static uint8_t get_ftdm_val(ftdm2trillium_t *vals, uint8_t trillium_val, uint8_t default_val);
|
||||
ftdm_status_t get_calling_name_from_usr_usr(ftdm_channel_t *ftdmchan, UsrUsr *usrUsr);
|
||||
|
@ -71,6 +80,28 @@ ftdm2trillium_t ton_codes[] = {
|
|||
{FTDM_TON_RESERVED, IN_TON_EXT},
|
||||
};
|
||||
|
||||
ftdm2trillium_t nsf_spec_codes[] = {
|
||||
{SNGISDN_NETSPECFAC_SPEC_ACCUNET, 0xe6},
|
||||
{SNGISDN_NETSPECFAC_SPEC_MEGACOM, 0xe3},
|
||||
{SNGISDN_NETSPECFAC_SPEC_MEGACOM_800, 0xe2},
|
||||
{SNGISDN_NETSPECFAC_SPEC_SDDN, 0xe1},
|
||||
{SNGISDN_NETSPECFAC_SPEC_INVALID, 0x00},
|
||||
};
|
||||
|
||||
ftdm2trillium_t nsf_type_codes[] = {
|
||||
{SNGISDN_NETSPECFAC_TYPE_USER_SPEC, 0x00},
|
||||
{SNGISDN_NETSPECFAC_TYPE_NATIONAL_NETWORK_IDENT, 0x02},
|
||||
{SNGISDN_NETSPECFAC_TYPE_INTERNATIONAL_NETWORK_IDENT, 0x03},
|
||||
{SNGISDN_NETSPECFAC_TYPE_INVALID, 0x00},
|
||||
};
|
||||
|
||||
ftdm2trillium_t nsf_plan_codes[] = {
|
||||
{SNGISDN_NETSPECFAC_PLAN_UNKNOWN, 0x00},
|
||||
{SNGISDN_NETSPECFAC_PLAN_CARRIER_IDENT, 0x01},
|
||||
{SNGISDN_NETSPECFAC_PLAN_DATA_NETWORK_IDENT, 0x03},
|
||||
{SNGISDN_NETSPECFAC_PLAN_INVALID, 0x00},
|
||||
};
|
||||
|
||||
static uint8_t get_trillium_val(ftdm2trillium_t *vals, uint8_t ftdm_val, uint8_t default_val)
|
||||
{
|
||||
ftdm2trillium_t *val = vals;
|
||||
|
@ -530,6 +561,29 @@ ftdm_status_t get_prog_ind_ie(ftdm_channel_t *ftdmchan, ProgInd *progInd)
|
|||
}
|
||||
|
||||
|
||||
ftdm_status_t get_network_specific_fac(ftdm_channel_t *ftdmchan, NetFac *netFac)
|
||||
{
|
||||
if (!netFac->eh.pres) {
|
||||
return FTDM_FAIL;
|
||||
}
|
||||
|
||||
if (netFac->netFacSpec.pres == PRSNT_NODEF) {
|
||||
char digits_string [32];
|
||||
memcpy(digits_string, (const char*)netFac->netFacSpec.val, netFac->netFacSpec.len);
|
||||
digits_string[netFac->netFacSpec.len] = '\0';
|
||||
sngisdn_add_var((sngisdn_chan_data_t*)ftdmchan->call_data, "isdn.netFac.spec", digits_string);
|
||||
}
|
||||
|
||||
if (netFac->typeNetId.pres == PRSNT_NODEF) {
|
||||
sngisdn_add_var((sngisdn_chan_data_t*)ftdmchan->call_data, "isdn.netFac.type", ftdm_sngisdn_netspecfac_type2str(get_ftdm_val(nsf_type_codes, netFac->typeNetId.val, 0x00)));
|
||||
}
|
||||
|
||||
if (netFac->netIdPlan.pres == PRSNT_NODEF) {
|
||||
sngisdn_add_var((sngisdn_chan_data_t*)ftdmchan->call_data, "isdn.netFac.plan", ftdm_sngisdn_netspecfac_type2str(get_ftdm_val(nsf_plan_codes, netFac->netIdPlan.val, 0x00)));
|
||||
}
|
||||
return FTDM_SUCCESS;
|
||||
}
|
||||
|
||||
ftdm_status_t set_calling_num(ftdm_channel_t *ftdmchan, CgPtyNmb *cgPtyNmb)
|
||||
{
|
||||
ftdm_caller_data_t *caller_data = &ftdmchan->caller_data;
|
||||
|
@ -900,6 +954,67 @@ ftdm_status_t set_prog_ind_ie(ftdm_channel_t *ftdmchan, ProgInd *progInd, ftdm_s
|
|||
return FTDM_SUCCESS;
|
||||
}
|
||||
|
||||
ftdm_status_t set_network_specific_fac(ftdm_channel_t *ftdmchan, NetFac *netFac)
|
||||
{
|
||||
const char *str = NULL;
|
||||
|
||||
str = ftdm_usrmsg_get_var(ftdmchan->usrmsg, "isdn.netFac.spec");
|
||||
if (ftdm_strlen_zero(str)) {
|
||||
/* Network-specific facility specification is mandatory, cannot send IE
|
||||
without it */
|
||||
return FTDM_SUCCESS;
|
||||
} else {
|
||||
ftdm_sngisdn_netspecfac_spec_t spec = ftdm_str2ftdm_sngisdn_netspecfac_spec(str);
|
||||
|
||||
netFac->eh.pres = PRSNT_NODEF;
|
||||
netFac->netFacSpec.pres = PRSNT_NODEF;
|
||||
|
||||
if (spec == SNGISDN_NETSPECFAC_SPEC_INVALID) {
|
||||
int byte = 0;
|
||||
ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "Non-standard NSF specified:%s\n", str);
|
||||
|
||||
if (sscanf(str, "%x", &byte) == 1) {
|
||||
netFac->netFacSpec.val[0] = byte & 0xFF;
|
||||
}
|
||||
|
||||
netFac->netFacSpec.len = 1;
|
||||
} else {
|
||||
/* User is using one of the pre-specified NSF's */
|
||||
netFac->netFacSpec.val[0] = get_trillium_val(nsf_spec_codes, spec, 0x00);
|
||||
netFac->netFacSpec.len = 1;
|
||||
}
|
||||
}
|
||||
|
||||
netFac->lenNetId.pres = PRSNT_NODEF;
|
||||
netFac->lenNetId.val = 0;
|
||||
|
||||
str = ftdm_usrmsg_get_var(ftdmchan->usrmsg, "isdn.netFac.type");
|
||||
if (!ftdm_strlen_zero(str)) {
|
||||
netFac->typeNetId.pres = PRSNT_NODEF;
|
||||
netFac->typeNetId.val = ftdm_str2ftdm_sngisdn_netspecfac_type(str);
|
||||
}
|
||||
|
||||
str = ftdm_usrmsg_get_var(ftdmchan->usrmsg, "isdn.netFac.plan");
|
||||
if (!ftdm_strlen_zero(str)) {
|
||||
netFac->netIdPlan.pres = PRSNT_NODEF;
|
||||
netFac->netIdPlan.val = ftdm_str2ftdm_sngisdn_netspecfac_plan(str);
|
||||
}
|
||||
|
||||
if (netFac->netIdPlan.pres == PRSNT_NODEF || netFac->typeNetId.pres == PRSNT_NODEF) {
|
||||
netFac->lenNetId.val++;
|
||||
}
|
||||
|
||||
str = ftdm_usrmsg_get_var(ftdmchan->usrmsg, "isdn.netFac.ident");
|
||||
if (!ftdm_strlen_zero(str)) {
|
||||
netFac->lenNetId.val++;
|
||||
|
||||
netFac->netId.pres = PRSNT_NODEF;
|
||||
memcpy(netFac->netId.val, str, strlen(str));
|
||||
}
|
||||
|
||||
return FTDM_SUCCESS;
|
||||
}
|
||||
|
||||
ftdm_status_t set_user_to_user_ie(ftdm_channel_t *ftdmchan, UsrUsr *usrUsr)
|
||||
{
|
||||
sngisdn_chan_data_t *sngisdn_info = ftdmchan->call_data;
|
||||
|
|
|
@ -771,7 +771,7 @@ uint32_t sngisdn_decode_ie(char *str, uint32_t *str_len, uint8_t current_codeset
|
|||
default:
|
||||
{
|
||||
*str_len += sprintf(&str[*str_len], "Undecoded");
|
||||
print_hex_dump((char*)str, str_len, data, index_start, index_end);
|
||||
print_hex_dump((char*)str, str_len, data, index_start, index_end + 1);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -101,6 +101,42 @@ typedef enum {
|
|||
#define SNGISDN_PROGIND_LOC_STRINGS "user", "private-net-local-user", "public-net-local-user", "transit-network", "public-net-remote-user", "private-net-remote-user", "beyond-interworking", "invalid"
|
||||
SNGISDN_STR2ENUM_P(ftdm_str2ftdm_sngisdn_progind_loc, ftdm_sngisdn_progind_loc2str, ftdm_sngisdn_progind_loc_t);
|
||||
|
||||
typedef enum {
|
||||
/* User Specified */
|
||||
SNGISDN_NETSPECFAC_TYPE_USER_SPEC,
|
||||
/* National network identification */
|
||||
SNGISDN_NETSPECFAC_TYPE_NATIONAL_NETWORK_IDENT,
|
||||
/* International network identification */
|
||||
SNGISDN_NETSPECFAC_TYPE_INTERNATIONAL_NETWORK_IDENT,
|
||||
/* Invalid */
|
||||
SNGISDN_NETSPECFAC_TYPE_INVALID,
|
||||
} ftdm_sngisdn_netspecfac_type_t;
|
||||
#define SNGISDN_NETSPECFAC_TYPE_STRINGS "user-specified", "national-network-identification", "national-network-identification", "invalid"
|
||||
SNGISDN_STR2ENUM_P(ftdm_str2ftdm_sngisdn_netspecfac_type, ftdm_sngisdn_netspecfac_type2str, ftdm_sngisdn_netspecfac_type_t);
|
||||
|
||||
typedef enum {
|
||||
/* Unknown */
|
||||
SNGISDN_NETSPECFAC_PLAN_UNKNOWN,
|
||||
/* Carrier Identification Code */
|
||||
SNGISDN_NETSPECFAC_PLAN_CARRIER_IDENT,
|
||||
/* Data network identification code */
|
||||
SNGISDN_NETSPECFAC_PLAN_DATA_NETWORK_IDENT,
|
||||
/* Invalid */
|
||||
SNGISDN_NETSPECFAC_PLAN_INVALID,
|
||||
} ftdm_sngisdn_netspecfac_plan_t;
|
||||
#define SNGISDN_NETSPECFAC_PLAN_STRINGS "unknown", "carrier-identification", "data-network-identification", "invalid"
|
||||
SNGISDN_STR2ENUM_P(ftdm_str2ftdm_sngisdn_netspecfac_plan, ftdm_sngisdn_netspecfac_plan2str, ftdm_sngisdn_netspecfac_plan_t);
|
||||
|
||||
typedef enum {
|
||||
/* Unknown */
|
||||
SNGISDN_NETSPECFAC_SPEC_ACCUNET,
|
||||
SNGISDN_NETSPECFAC_SPEC_MEGACOM,
|
||||
SNGISDN_NETSPECFAC_SPEC_MEGACOM_800,
|
||||
SNGISDN_NETSPECFAC_SPEC_SDDN,
|
||||
SNGISDN_NETSPECFAC_SPEC_INVALID,
|
||||
} ftdm_sngisdn_netspecfac_spec_t;
|
||||
#define SNGISDN_NETSPECFAC_SPEC_STRINGS "accunet", "megacom", "megacom-800", "sddn", "invalid"
|
||||
SNGISDN_STR2ENUM_P(ftdm_str2ftdm_sngisdn_netspecfac_spec, ftdm_sngisdn_netspecfac_spec2str, ftdm_sngisdn_netspecfac_spec_t);
|
||||
|
||||
#endif /* __FTMOD_SANGOMA_ISDN_USER_H__*/
|
||||
|
||||
|
|
Loading…
Reference in New Issue