diff --git a/libs/freetdm/mod_freetdm/mod_freetdm.c b/libs/freetdm/mod_freetdm/mod_freetdm.c index 27dc8d8c92..07d4e88f33 100755 --- a/libs/freetdm/mod_freetdm/mod_freetdm.c +++ b/libs/freetdm/mod_freetdm/mod_freetdm.c @@ -149,6 +149,7 @@ static switch_call_cause_t channel_outgoing_channel(switch_core_session_t *sessi static switch_status_t channel_read_frame(switch_core_session_t *session, switch_frame_t **frame, switch_io_flag_t flags, int stream_id); static switch_status_t channel_write_frame(switch_core_session_t *session, switch_frame_t *frame, switch_io_flag_t flags, int stream_id); static switch_status_t channel_kill_channel(switch_core_session_t *session, int sig); +static const char* channel_get_variable(switch_core_session_t *session, switch_event_t *var_event, const char *variable_name); ftdm_status_t ftdm_channel_from_event(ftdm_sigmsg_t *sigmsg, switch_core_session_t **sp); void dump_chan(ftdm_span_t *span, uint32_t chan_id, switch_stream_handle_t *stream); void dump_chan_xml(ftdm_span_t *span, uint32_t chan_id, switch_stream_handle_t *stream); @@ -1049,6 +1050,27 @@ switch_io_routines_t freetdm_io_routines = { /*.receive_message*/ channel_receive_message }; +static const char* channel_get_variable(switch_core_session_t *session, switch_event_t *var_event, const char *variable_name) +{ + const char *variable = NULL; + + if (var_event) { + if ((variable = switch_event_get_header(var_event, variable_name))) { + return variable; + } + } + if (session) { + switch_channel_t *channel = switch_core_session_get_channel(session); + if ((variable = switch_channel_get_variable(channel, variable_name))) { + return variable; + } + } + if ((variable = switch_core_get_variable(variable_name))) { + return variable; + } + return NULL; +} + /* Make sure when you have 2 sessions in the same scope that you pass the appropriate one to the routines that allocate memory or you will have 1 channel with memory allocated from another channel's pool! */ @@ -1226,20 +1248,6 @@ static switch_call_cause_t channel_outgoing_channel(switch_core_session_t *sessi } } - if (session) { - /* take out some other values from the session if they're present */ - switch_channel_t *channel = switch_core_session_get_channel(session); - const char *freetdmvar; - freetdmvar = switch_channel_get_variable(channel, "freetdm_bearer_capability"); - if (freetdmvar) { - caller_data.bearer_capability = (uint8_t)atoi(freetdmvar); - } - freetdmvar = switch_channel_get_variable(channel, "freetdm_bearer_layer1"); - if (freetdmvar) { - caller_data.bearer_layer1 = (uint8_t)atoi(freetdmvar); - } - } - if (switch_test_flag(outbound_profile, SWITCH_CPF_SCREEN)) { caller_data.screen = 1; } @@ -1248,29 +1256,37 @@ static switch_call_cause_t channel_outgoing_channel(switch_core_session_t *sessi caller_data.pres = 1; } - if (!zstr(dest)) { - ftdm_set_string(caller_data.dnis.digits, dest); + if ((var = channel_get_variable(session, var_event, "freetdm_bearer_capability"))) { + caller_data.bearer_capability = (uint8_t)atoi(var); } - if ((var = switch_event_get_header(var_event, "freetdm_outbound_ton")) || (var = switch_core_get_variable("freetdm_outbound_ton"))) { - if (!strcasecmp(var, "national")) { - caller_data.dnis.type = FTDM_TON_NATIONAL; - } else if (!strcasecmp(var, "international")) { - caller_data.dnis.type = FTDM_TON_INTERNATIONAL; - } else if (!strcasecmp(var, "local")) { - caller_data.dnis.type = FTDM_TON_SUBSCRIBER_NUMBER; - } else if (!strcasecmp(var, "unknown")) { - caller_data.dnis.type = FTDM_TON_UNKNOWN; - } + if ((var = channel_get_variable(session, var_event, "freetdm_bearer_layer1"))) { + caller_data.bearer_layer1 = (uint8_t)atoi(var); + } + + if ((var = channel_get_variable(session, var_event, "freetdm_screening_ind"))) { + ftdm_set_screening_ind(var, &caller_data.screen); + } + + if ((var = channel_get_variable(session, var_event, "freetdm_presentation_ind"))) { + ftdm_set_presentation_ind(var, &caller_data.pres); + } + + if ((var = channel_get_variable(session, var_event, "freetdm_outbound_ton"))) { + ftdm_set_ton(var, &caller_data.dnis.type); } else { caller_data.dnis.type = outbound_profile->destination_number_ton; } - if ((var = switch_event_get_header(var_event, "freetdm_custom_call_data")) || (var = switch_core_get_variable("freetdm_custom_call_data"))) { + if ((var = channel_get_variable(session, var_event, "freetdm_custom_call_data"))) { ftdm_set_string(caller_data.raw_data, var); caller_data.raw_data_len = (uint32_t)strlen(var); } + if (!zstr(dest)) { + ftdm_set_string(caller_data.dnis.digits, dest); + } + caller_data.dnis.plan = outbound_profile->destination_number_numplan; /* blindly copy data from outbound_profile. They will be overwritten @@ -2074,6 +2090,9 @@ static FIO_SIGNAL_CB_FUNCTION(on_clear_channel_signal) switch(sigmsg->event_id) { case FTDM_SIGEVENT_START: { + ftdm_channel_add_var(sigmsg->channel, "screening_ind", ftdm_screening2str(caller_data->screen)); + ftdm_channel_add_var(sigmsg->channel, "presentation_ind", ftdm_presentation2str(caller_data->pres)); + ftdm_enable_channel_dtmf(sigmsg->channel, NULL); return ftdm_channel_from_event(sigmsg, &session); } diff --git a/libs/freetdm/src/ftdm_call_utils.c b/libs/freetdm/src/ftdm_call_utils.c index d91b3bc9e2..52d2557a01 100644 --- a/libs/freetdm/src/ftdm_call_utils.c +++ b/libs/freetdm/src/ftdm_call_utils.c @@ -36,80 +36,101 @@ #include -FT_DECLARE(ftdm_status_t) ftdm_span_set_npi(const char *npi_string, uint8_t *target) +FT_DECLARE(ftdm_status_t) ftdm_set_npi(const char *string, uint8_t *target) { - if (!strcasecmp(npi_string, "isdn") || !strcasecmp(npi_string, "e164")) { - *target = FTDM_NPI_ISDN; - } else if (!strcasecmp(npi_string, "data")) { - *target = FTDM_NPI_DATA; - } else if (!strcasecmp(npi_string, "telex")) { - *target = FTDM_NPI_TELEX; - } else if (!strcasecmp(npi_string, "national")) { - *target = FTDM_NPI_NATIONAL; - } else if (!strcasecmp(npi_string, "private")) { - *target = FTDM_NPI_PRIVATE; - } else if (!strcasecmp(npi_string, "reserved")) { - *target = FTDM_NPI_RESERVED; - } else if (!strcasecmp(npi_string, "unknown")) { - *target = FTDM_NPI_UNKNOWN; - } else { - ftdm_log(FTDM_LOG_WARNING, "Invalid NPI value (%s)\n", npi_string); - *target = FTDM_NPI_UNKNOWN; - return FTDM_FAIL; + int val; + ftdm_status_t status = FTDM_SUCCESS; + + val = ftdm_str2ftdm_npi(string); + if (val == FTDM_NPI_INVALID) { + ftdm_log(FTDM_LOG_WARNING, "Invalid NPI string (%s)\n", string); + status = FTDM_FAIL; + val = FTDM_NPI_UNKNOWN; } - return FTDM_SUCCESS; + *target = val; + return status; } -FT_DECLARE(ftdm_status_t) ftdm_span_set_ton(const char *ton_string, uint8_t *target) +FT_DECLARE(ftdm_status_t) ftdm_set_ton(const char *string, uint8_t *target) { - if (!strcasecmp(ton_string, "national")) { - *target = FTDM_TON_NATIONAL; - } else if (!strcasecmp(ton_string, "international")) { - *target = FTDM_TON_INTERNATIONAL; - } else if (!strcasecmp(ton_string, "local")) { - *target = FTDM_TON_SUBSCRIBER_NUMBER; - } else if (!strcasecmp(ton_string, "unknown")) { - *target = FTDM_TON_UNKNOWN; - } else { - ftdm_log(FTDM_LOG_WARNING, "Invalid TON value (%s)\n", ton_string); - *target = FTDM_TON_UNKNOWN; - return FTDM_FAIL; + int val; + ftdm_status_t status = FTDM_SUCCESS; + + val = ftdm_str2ftdm_ton(string); + if (val == FTDM_TON_INVALID) { + ftdm_log(FTDM_LOG_WARNING, "Invalid TON string (%s)\n", string); + status = FTDM_FAIL; + val = FTDM_TON_UNKNOWN; } - return FTDM_SUCCESS; + *target = val; + return status; } -FT_DECLARE(ftdm_status_t) ftdm_span_set_bearer_capability(const char *bc_string, ftdm_bearer_cap_t *target) +FT_DECLARE(ftdm_status_t) ftdm_set_bearer_capability(const char *string, uint8_t *target) { - if (!strcasecmp(bc_string, "speech")) { - *target = FTDM_BEARER_CAP_SPEECH; - } else if (!strcasecmp(bc_string, "unrestricted-digital")) { - *target = FTDM_BEARER_CAP_64K_UNRESTRICTED; - } else if (!strcasecmp(bc_string, "3.1Khz")) { - *target = FTDM_BEARER_CAP_3_1KHZ_AUDIO; - } else { - ftdm_log(FTDM_LOG_WARNING, "Unsupported Bearer Capability value (%s)\n", bc_string); - return FTDM_FAIL; + int val; + ftdm_status_t status = FTDM_SUCCESS; + + val = ftdm_str2ftdm_bearer_cap(string); + if (val == FTDM_NPI_INVALID) { + ftdm_log(FTDM_LOG_WARNING, "Invalid Bearer-Capability string (%s)\n", string); + status = FTDM_FAIL; + val = FTDM_BEARER_CAP_SPEECH; } - return FTDM_SUCCESS; + + *target = val; + return status; } -FT_DECLARE(ftdm_status_t) ftdm_span_set_bearer_layer1(const char *bc_string, ftdm_user_layer1_prot_t *target) +FT_DECLARE(ftdm_status_t) ftdm_set_bearer_layer1(const char *string, uint8_t *target) { - if (!strcasecmp(bc_string, "v110")) { - *target = FTDM_USER_LAYER1_PROT_V110; - } else if (!strcasecmp(bc_string, "ulaw")) { - *target = FTDM_USER_LAYER1_PROT_ULAW; - } else if (!strcasecmp(bc_string, "alaw")) { - *target =FTDM_USER_LAYER1_PROT_ALAW ; - } else { - ftdm_log(FTDM_LOG_WARNING, "Unsupported Bearer Layer1 Prot value (%s)\n", bc_string); - return FTDM_FAIL; + int val; + ftdm_status_t status = FTDM_SUCCESS; + + val = ftdm_str2ftdm_usr_layer1_prot(string); + if (val == FTDM_USER_LAYER1_PROT_INVALID) { + ftdm_log(FTDM_LOG_WARNING, "Invalid Bearer Layer 1 Protocol string (%s)\n", string); + status = FTDM_FAIL; + val = FTDM_USER_LAYER1_PROT_ULAW; } - return FTDM_SUCCESS; + + *target = val; + return status; } +FT_DECLARE(ftdm_status_t) ftdm_set_screening_ind(const char *string, uint8_t *target) +{ + int val; + ftdm_status_t status = FTDM_SUCCESS; -FT_DECLARE(ftdm_status_t) ftdm_is_number(char *number) + val = ftdm_str2ftdm_screening(string); + if (val == FTDM_SCREENING_INVALID) { + ftdm_log(FTDM_LOG_WARNING, "Invalid screening indicator string (%s)\n", string); + status = FTDM_FAIL; + val = FTDM_SCREENING_NOT_SCREENED; + } + + *target = val; + return status; +} + +FT_DECLARE(ftdm_status_t) ftdm_set_presentation_ind(const char *string, uint8_t *target) +{ + int val; + ftdm_status_t status = FTDM_SUCCESS; + + val = ftdm_str2ftdm_presentation(string); + if (val == FTDM_PRES_INVALID) { + ftdm_log(FTDM_LOG_WARNING, "Invalid presentation string (%s)\n", string); + status = FTDM_FAIL; + val = FTDM_PRES_ALLOWED; + } + + *target = val; + return status; +} + +FT_DECLARE(ftdm_status_t) ftdm_is_number(const char *number) { if (!number) { return FTDM_FAIL; diff --git a/libs/freetdm/src/ftdm_io.c b/libs/freetdm/src/ftdm_io.c index ede3ff8fc8..3e48586a4e 100644 --- a/libs/freetdm/src/ftdm_io.c +++ b/libs/freetdm/src/ftdm_io.c @@ -150,6 +150,24 @@ FTDM_STR2ENUM(ftdm_str2ftdm_chan_type, ftdm_chan_type2str, ftdm_chan_type_t, CHA FTDM_ENUM_NAMES(SIGNALING_STATUS_NAMES, SIGSTATUS_STRINGS) FTDM_STR2ENUM(ftdm_str2ftdm_signaling_status, ftdm_signaling_status2str, ftdm_signaling_status_t, SIGNALING_STATUS_NAMES, FTDM_SIG_STATE_INVALID) +FTDM_ENUM_NAMES(TON_NAMES, TON_STRINGS) +FTDM_STR2ENUM(ftdm_str2ftdm_ton, ftdm_ton2str, ftdm_ton_t, TON_NAMES, FTDM_TON_INVALID) + +FTDM_ENUM_NAMES(NPI_NAMES, NPI_STRINGS) +FTDM_STR2ENUM(ftdm_str2ftdm_npi, ftdm_npi2str, ftdm_npi_t, NPI_NAMES, FTDM_NPI_INVALID) + +FTDM_ENUM_NAMES(PRESENTATION_NAMES, PRESENTATION_STRINGS) +FTDM_STR2ENUM(ftdm_str2ftdm_presentation, ftdm_presentation2str, ftdm_presentation_t, PRESENTATION_NAMES, FTDM_PRES_INVALID) + +FTDM_ENUM_NAMES(SCREENING_NAMES, SCREENING_STRINGS) +FTDM_STR2ENUM(ftdm_str2ftdm_screening, ftdm_screening2str, ftdm_screening_t, SCREENING_NAMES, FTDM_SCREENING_INVALID) + +FTDM_ENUM_NAMES(BEARER_CAP_NAMES, BEARER_CAP_STRINGS) +FTDM_STR2ENUM(ftdm_str2ftdm_bearer_cap, ftdm_bearer_cap2str, ftdm_bearer_cap_t, BEARER_CAP_NAMES, FTDM_BEARER_CAP_INVALID) + +FTDM_ENUM_NAMES(USER_LAYER1_PROT_NAMES, USER_LAYER1_PROT_STRINGS) +FTDM_STR2ENUM(ftdm_str2ftdm_usr_layer1_prot, ftdm_user_layer1_prot2str, ftdm_user_layer1_prot_t, USER_LAYER1_PROT_NAMES, FTDM_USER_LAYER1_PROT_INVALID) + static ftdm_status_t ftdm_group_add_channels(ftdm_span_t* span, int currindex, const char* name); static const char *cut_path(const char *in) @@ -4822,7 +4840,7 @@ FT_DECLARE(ftdm_status_t) ftdm_span_send_signal(ftdm_span_t *span, ftdm_sigmsg_t if (sigmsg->channel) { ftdm_mutex_lock(sigmsg->channel->mutex); } - + /* some core things to do on special events */ switch (sigmsg->event_id) { diff --git a/libs/freetdm/src/ftmod/ftmod_sangoma_boost/ftdm_sangoma_boost.h b/libs/freetdm/src/ftmod/ftmod_sangoma_boost/ftdm_sangoma_boost.h index 5a3ca76c56..6fbf272d07 100644 --- a/libs/freetdm/src/ftmod/ftmod_sangoma_boost/ftdm_sangoma_boost.h +++ b/libs/freetdm/src/ftmod/ftmod_sangoma_boost/ftdm_sangoma_boost.h @@ -58,7 +58,7 @@ typedef struct ftdm_sangoma_boost_trunkgroup { ftdm_size_t size; /* Number of b-channels in group */ unsigned int last_used_index; /* index of last b-channel used */ ftdm_channel_t* ftdmchans[MAX_CHANS_PER_TRUNKGROUP]; - //DAVIDY need to merge congestion timeouts to this struct + //TODO need to merge congestion timeouts to this struct } ftdm_sangoma_boost_trunkgroup_t; #endif diff --git a/libs/freetdm/src/ftmod/ftmod_sangoma_boost/ftmod_sangoma_boost.c b/libs/freetdm/src/ftmod/ftmod_sangoma_boost/ftmod_sangoma_boost.c index c9691e232b..50a01cc0ec 100644 --- a/libs/freetdm/src/ftmod/ftmod_sangoma_boost/ftmod_sangoma_boost.c +++ b/libs/freetdm/src/ftmod/ftmod_sangoma_boost/ftmod_sangoma_boost.c @@ -55,7 +55,7 @@ ftdm_mutex_t *g_boost_modules_mutex = NULL; ftdm_hash_t *g_boost_modules_hash = NULL; #define MAX_TRUNK_GROUPS 64 -//DAVIDY need to merge congestion_timeouts with ftdm_sangoma_boost_trunkgroups +//TODO need to merge congestion_timeouts with ftdm_sangoma_boost_trunkgroups static time_t congestion_timeouts[MAX_TRUNK_GROUPS]; static ftdm_sangoma_boost_trunkgroup_t *g_trunkgroups[MAX_TRUNK_GROUPS]; @@ -2582,17 +2582,17 @@ static FIO_CONFIGURE_SPAN_SIGNALING_FUNCTION(ftdm_sangoma_boost_configure_span) } else if (!strcasecmp(var, "remote_port")) { remote_port = atoi(val); } else if (!strcasecmp(var, "outbound-called-ton")) { - ftdm_span_set_ton(val, &span->default_caller_data.dnis.type); + ftdm_set_ton(val, &span->default_caller_data.dnis.type); } else if (!strcasecmp(var, "outbound-called-npi")) { - ftdm_span_set_npi(val, &span->default_caller_data.dnis.plan); + ftdm_set_npi(val, &span->default_caller_data.dnis.plan); } else if (!strcasecmp(var, "outbound-calling-ton")) { - ftdm_span_set_ton(val, &span->default_caller_data.cid_num.type); + ftdm_set_ton(val, &span->default_caller_data.cid_num.type); } else if (!strcasecmp(var, "outbound-calling-npi")) { - ftdm_span_set_npi(val, &span->default_caller_data.cid_num.plan); + ftdm_set_npi(val, &span->default_caller_data.cid_num.plan); } else if (!strcasecmp(var, "outbound-rdnis-ton")) { - ftdm_span_set_ton(val, &span->default_caller_data.rdnis.type); + ftdm_set_ton(val, &span->default_caller_data.rdnis.type); } else if (!strcasecmp(var, "outbound-rdnis-npi")) { - ftdm_span_set_npi(val, &span->default_caller_data.rdnis.plan); + ftdm_set_npi(val, &span->default_caller_data.rdnis.plan); } else if (!sigmod) { snprintf(span->last_error, sizeof(span->last_error), "Unknown parameter [%s]", var); FAIL_CONFIG_RETURN(FTDM_FAIL); diff --git a/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn.c b/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn.c index 6f5f838590..8831ac4185 100644 --- a/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn.c +++ b/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn.c @@ -40,8 +40,8 @@ #include #endif -static void *ftdm_sangoma_isdn_run(ftdm_thread_t *me, void *obj); +static void *ftdm_sangoma_isdn_run(ftdm_thread_t *me, void *obj); static ftdm_status_t ftdm_sangoma_isdn_stop(ftdm_span_t *span); static ftdm_status_t ftdm_sangoma_isdn_start(ftdm_span_t *span); @@ -673,7 +673,8 @@ static void ftdm_sangoma_isdn_process_state_change(ftdm_channel_t *ftdmchan) break; case FTDM_CHANNEL_STATE_RINGING: { - sngisdn_snd_alert(ftdmchan, SNGISDN_PROGIND_NETE_ISDN); + ftdm_sngisdn_progind_t prog_ind = {SNGISDN_PROGIND_LOC_USER, SNGISDN_PROGIND_DESCR_NETE_ISDN}; + sngisdn_snd_alert(ftdmchan, prog_ind); } break; case FTDM_CHANNEL_STATE_PROGRESS: @@ -687,7 +688,8 @@ static void ftdm_sangoma_isdn_process_state_change(ftdm_channel_t *ftdmchan) /* If we already sent a PROCEED before, do not send a PROGRESS as there is nothing to indicate to the remote switch */ if (ftdmchan->last_state != FTDM_CHANNEL_STATE_PROCEED) { /* Send a progress message, indicating: Call is not end-to-end ISDN, further call progress may be available */ - sngisdn_snd_progress(ftdmchan, SNGISDN_PROGIND_NETE_ISDN); + ftdm_sngisdn_progind_t prog_ind = {SNGISDN_PROGIND_LOC_USER, SNGISDN_PROGIND_DESCR_NETE_ISDN}; + sngisdn_snd_progress(ftdmchan, prog_ind); } } } @@ -699,7 +701,8 @@ static void ftdm_sangoma_isdn_process_state_change(ftdm_channel_t *ftdmchan) ftdm_span_send_signal(ftdmchan->span, &sigev); } else { /* Send a progress message, indicating: In-band information/pattern available */ - sngisdn_snd_progress(ftdmchan, SNGISDN_PROGIND_IB_AVAIL); + ftdm_sngisdn_progind_t prog_ind = {SNGISDN_PROGIND_LOC_USER, SNGISDN_PROGIND_DESCR_IB_AVAIL}; + sngisdn_snd_progress(ftdmchan, prog_ind); } } break; diff --git a/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn.h b/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn.h index a82ed283e1..6957f9925e 100644 --- a/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn.h +++ b/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn.h @@ -138,17 +138,47 @@ typedef enum { typedef enum { /* Call is not end-to-end ISDN */ - SNGISDN_PROGIND_NETE_ISDN = 1, + SNGISDN_PROGIND_DESCR_NETE_ISDN, /* Destination address is non-ISDN */ - SNGISDN_PROGIND_DEST_NISDN, + SNGISDN_PROGIND_DESCR_DEST_NISDN, /* Origination address is non-ISDN */ - SNGISDN_PROGIND_ORIG_NISDN, + SNGISDN_PROGIND_DESCR_ORIG_NISDN, /* Call has returned to the ISDN */ - SNGISDN_PROGIND_RET_ISDN, + SNGISDN_PROGIND_DESCR_RET_ISDN, /* Interworking as occured and has resulted in a telecommunication service change */ - SNGISDN_PROGIND_SERV_CHANGE, - /* In-band information or an appropriate pattern is now available */ - SNGISDN_PROGIND_IB_AVAIL, + SNGISDN_PROGIND_DESCR_SERV_CHANGE, + /* In-band information or an appropriate pattern is now available */ + SNGISDN_PROGIND_DESCR_IB_AVAIL, + /* Invalid */ + SNGISDN_PROGIND_DESCR_INVALID, +} ftdm_sngisdn_progind_descr_t; +#define SNGISDN_PROGIND_DESCR_STRINGS "not-end-to-end-isdn", "destination-is-non-isdn", "origination-is-non-isdn", "call-returned-to-isdn", "service-change", "inband-info-available", "invalid" +FTDM_STR2ENUM_P(ftdm_str2ftdm_sngisdn_progind_descr, ftdm_sngisdn_progind_descr2str, ftdm_sngisdn_progind_descr_t); + +typedef enum { + /* User */ + SNGISDN_PROGIND_LOC_USER, + /* Private network serving the local user */ + SNGISDN_PROGIND_LOC_PRIV_NET_LOCAL_USR, + /* Public network serving the local user */ + SNGISDN_PROGIND_LOC_PUB_NET_LOCAL_USR, + /* Transit network */ + SNGISDN_PROGIND_LOC_TRANSIT_NET, + /* Public network serving remote user */ + SNGISDN_PROGIND_LOC_PUB_NET_REMOTE_USR, + /* Private network serving remote user */ + SNGISDN_PROGIND_LOC_PRIV_NET_REMOTE_USR, + /* Network beyond the interworking point */ + SNGISDN_PROGIND_LOC_NET_BEYOND_INTRW, + /* Invalid */ + SNGISDN_PROGIND_LOC_INVALID, +} ftdm_sngisdn_progind_loc_t; +#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" +FTDM_STR2ENUM_P(ftdm_str2ftdm_sngisdn_progind_loc, ftdm_sngisdn_progind_loc2str, ftdm_sngisdn_progind_loc_t); + +typedef struct ftdm_sngisdn_prog_ind { + ftdm_sngisdn_progind_loc_t loc; /* location */ + ftdm_sngisdn_progind_descr_t descr; /* description */ } ftdm_sngisdn_progind_t; /* Only timers that can be cancelled are listed here */ @@ -201,6 +231,7 @@ typedef struct sngisdn_span_data { uint8_t facility; int8_t facility_timeout; uint8_t num_local_numbers; + uint8_t ignore_cause_value; uint8_t timer_t3; char* local_numbers[SNGISDN_NUM_LOCAL_NUMBERS]; ftdm_sched_t *sched; @@ -376,18 +407,25 @@ void sngisdn_rcv_cc_ind(CcMngmt *status); void sngisdn_rcv_sng_log(uint8_t level, char *fmt,...); void sngisdn_rcv_sng_assert(char *message); -ftdm_status_t get_calling_num(ftdm_caller_data_t *ftdm, CgPtyNmb *cgPtyNmb); -ftdm_status_t get_called_num(ftdm_caller_data_t *ftdm, CdPtyNmb *cdPtyNmb); -ftdm_status_t get_redir_num(ftdm_caller_data_t *ftdm, RedirNmb *redirNmb); -ftdm_status_t get_calling_name_from_display(ftdm_caller_data_t *ftdm, Display *display); -ftdm_status_t get_calling_name_from_usr_usr(ftdm_caller_data_t *ftdm, UsrUsr *usrUsr); -ftdm_status_t get_facility_ie(ftdm_caller_data_t *ftdm, uint8_t *data, uint32_t data_len); +ftdm_status_t get_calling_num(ftdm_channel_t *ftdmchan, CgPtyNmb *cgPtyNmb); +ftdm_status_t get_called_num(ftdm_channel_t *ftdmchan, CdPtyNmb *cdPtyNmb); +ftdm_status_t get_redir_num(ftdm_channel_t *ftdmchan, RedirNmb *redirNmb); +ftdm_status_t get_calling_name_from_display(ftdm_channel_t *ftdmchan, Display *display); +ftdm_status_t get_calling_name_from_usr_usr(ftdm_channel_t *ftdmchan, UsrUsr *usrUsr); +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, ftdm_size_t data_len); -ftdm_status_t set_calling_num(CgPtyNmb *cgPtyNmb, ftdm_caller_data_t *ftdm); -ftdm_status_t set_called_num(CdPtyNmb *cdPtyNmb, ftdm_caller_data_t *ftdm); -ftdm_status_t set_redir_num(RedirNmb *redirNmb, ftdm_caller_data_t *ftdm); -ftdm_status_t set_calling_name(ConEvnt *conEvnt, ftdm_channel_t *ftdmchan); +ftdm_status_t set_calling_num(ftdm_channel_t *ftdmchan, CgPtyNmb *cgPtyNmb); +ftdm_status_t set_called_num(ftdm_channel_t *ftdmchan, CdPtyNmb *cdPtyNmb); +ftdm_status_t set_redir_num(ftdm_channel_t *ftdmchan, RedirNmb *redirNmb); +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_facility_ie(ftdm_channel_t *ftdmchan, FacilityStr *facilityStr); +ftdm_status_t set_facility_ie_str(ftdm_channel_t *ftdmchan, uint8_t *data, ftdm_size_t *data_len); + uint8_t sngisdn_get_infoTranCap_from_stack(ftdm_bearer_cap_t bearer_capability); uint8_t sngisdn_get_usrInfoLyr1Prot_from_stack(ftdm_user_layer1_prot_t layer1_prot); diff --git a/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_cfg.c b/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_cfg.c index 657aa5e206..6b4e73ab25 100644 --- a/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_cfg.c +++ b/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_cfg.c @@ -34,13 +34,24 @@ #include "ftmod_sangoma_isdn.h" -ftdm_status_t parse_switchtype(const char* switch_name, ftdm_span_t *span); -ftdm_status_t parse_signalling(const char* signalling, ftdm_span_t *span); -ftdm_status_t add_local_number(const char* val, ftdm_span_t *span); +static ftdm_status_t parse_switchtype(const char* switch_name, ftdm_span_t *span); +static ftdm_status_t parse_signalling(const char* signalling, ftdm_span_t *span); +static ftdm_status_t add_local_number(const char* val, ftdm_span_t *span); +static ftdm_status_t parse_yesno(const char* var, const char* val, uint8_t *target); extern ftdm_sngisdn_data_t g_sngisdn_data; -ftdm_status_t add_local_number(const char* val, ftdm_span_t *span) +static ftdm_status_t parse_yesno(const char* var, const char* val, uint8_t *target) +{ + if (ftdm_true(val)) { + *target = SNGISDN_OPT_TRUE; + } else { + *target = SNGISDN_OPT_FALSE; + } + return FTDM_SUCCESS; +} + +static ftdm_status_t add_local_number(const char* val, ftdm_span_t *span) { sngisdn_span_data_t *signal_data = (sngisdn_span_data_t*) span->signal_data; @@ -53,7 +64,7 @@ ftdm_status_t add_local_number(const char* val, ftdm_span_t *span) return FTDM_SUCCESS; } -ftdm_status_t parse_switchtype(const char* switch_name, ftdm_span_t *span) +static ftdm_status_t parse_switchtype(const char* switch_name, ftdm_span_t *span) { unsigned i; ftdm_iterator_t *chaniter = NULL; @@ -160,7 +171,7 @@ ftdm_status_t parse_switchtype(const char* switch_name, ftdm_span_t *span) return FTDM_SUCCESS; } -ftdm_status_t parse_signalling(const char* signalling, ftdm_span_t *span) +static ftdm_status_t parse_signalling(const char* signalling, ftdm_span_t *span) { sngisdn_span_data_t *signal_data = (sngisdn_span_data_t*) span->signal_data; if (!strcasecmp(signalling, "net") || @@ -190,7 +201,8 @@ ftdm_status_t ftmod_isdn_parse_cfg(ftdm_conf_parameter_t *ftdm_parameters, ftdm_ signal_data->min_digits = 8; signal_data->overlap_dial = SNGISDN_OPT_DEFAULT; signal_data->setup_arb = SNGISDN_OPT_DEFAULT; - signal_data->facility_ie_decode = SNGISDN_OPT_TRUE; + signal_data->facility_ie_decode = SNGISDN_OPT_DEFAULT; + signal_data->ignore_cause_value = SNGISDN_OPT_DEFAULT; signal_data->timer_t3 = 8; signal_data->link_id = span->span_id; @@ -202,20 +214,19 @@ ftdm_status_t ftmod_isdn_parse_cfg(ftdm_conf_parameter_t *ftdm_parameters, ftdm_ if (span->trunk_type == FTDM_TRUNK_BRI || span->trunk_type == FTDM_TRUNK_BRI_PTMP) { - - ftdm_span_set_npi("unknown", &span->default_caller_data.dnis.plan); - ftdm_span_set_ton("unknown", &span->default_caller_data.dnis.type); - ftdm_span_set_npi("unknown", &span->default_caller_data.cid_num.plan); - ftdm_span_set_ton("unknown", &span->default_caller_data.cid_num.type); - ftdm_span_set_npi("unknown", &span->default_caller_data.rdnis.plan); - ftdm_span_set_ton("unknown", &span->default_caller_data.rdnis.type); + ftdm_set_npi("unknown", &span->default_caller_data.dnis.plan); + ftdm_set_ton("unknown", &span->default_caller_data.dnis.type); + ftdm_set_npi("unknown", &span->default_caller_data.cid_num.plan); + ftdm_set_ton("unknown", &span->default_caller_data.cid_num.type); + ftdm_set_npi("unknown", &span->default_caller_data.rdnis.plan); + ftdm_set_ton("unknown", &span->default_caller_data.rdnis.type); } else { - ftdm_span_set_npi("e164", &span->default_caller_data.dnis.plan); - ftdm_span_set_ton("national", &span->default_caller_data.dnis.type); - ftdm_span_set_npi("e164", &span->default_caller_data.cid_num.plan); - ftdm_span_set_ton("national", &span->default_caller_data.cid_num.type); - ftdm_span_set_npi("e164", &span->default_caller_data.rdnis.plan); - ftdm_span_set_ton("national", &span->default_caller_data.rdnis.type); + ftdm_set_npi("isdn", &span->default_caller_data.dnis.plan); + ftdm_set_ton("national", &span->default_caller_data.dnis.type); + ftdm_set_npi("isdn", &span->default_caller_data.cid_num.plan); + ftdm_set_ton("national", &span->default_caller_data.cid_num.type); + ftdm_set_npi("isdn", &span->default_caller_data.rdnis.plan); + ftdm_set_ton("national", &span->default_caller_data.rdnis.type); } for (paramindex = 0; ftdm_parameters[paramindex].var; paramindex++) { @@ -247,41 +258,29 @@ ftdm_status_t ftmod_isdn_parse_cfg(ftdm_conf_parameter_t *ftdm_parameters, ftdm_ } else { ftdm_log(FTDM_LOG_ERROR, "Invalid value for parameter:%s:%s\n", var, val); } - } else if (!strcasecmp(var, "setup arbitration")) { - if (!strcasecmp(val, "yes")) { - signal_data->setup_arb = SNGISDN_OPT_TRUE; - } else if (!strcasecmp(val, "no")) { - signal_data->setup_arb = SNGISDN_OPT_FALSE; - } else { - ftdm_log(FTDM_LOG_ERROR, "Invalid value for parameter:%s:%s\n", var, val); - } + } else if (!strcasecmp(var, "setup-arbitration")) { + parse_yesno(var, val, &signal_data->setup_arb); } else if (!strcasecmp(var, "facility")) { - if (!strcasecmp(val, "yes")) { - signal_data->facility = SNGISDN_OPT_TRUE; - } else if (!strcasecmp(val, "no")) { - signal_data->facility = SNGISDN_OPT_FALSE; - } else { - ftdm_log(FTDM_LOG_ERROR, "Invalid value for parameter:%s:%s\n", var, val); - } + parse_yesno(var, val, &signal_data->facility); } else if (!strcasecmp(var, "min_digits")) { signal_data->min_digits = atoi(val); } else if (!strcasecmp(var, "outbound-called-ton")) { - ftdm_span_set_ton(val, &span->default_caller_data.dnis.type); + ftdm_set_ton(val, &span->default_caller_data.dnis.type); } else if (!strcasecmp(var, "outbound-called-npi")) { - ftdm_span_set_npi(val, &span->default_caller_data.dnis.plan); + ftdm_set_npi(val, &span->default_caller_data.dnis.plan); } else if (!strcasecmp(var, "outbound-calling-ton")) { - ftdm_span_set_ton(val, &span->default_caller_data.cid_num.type); + ftdm_set_ton(val, &span->default_caller_data.cid_num.type); } else if (!strcasecmp(var, "outbound-calling-npi")) { - ftdm_span_set_npi(val, &span->default_caller_data.cid_num.plan); + ftdm_set_npi(val, &span->default_caller_data.cid_num.plan); } else if (!strcasecmp(var, "outbound-rdnis-ton")) { - ftdm_span_set_ton(val, &span->default_caller_data.rdnis.type); + ftdm_set_ton(val, &span->default_caller_data.rdnis.type); } else if (!strcasecmp(var, "outbound-rdnis-npi")) { - ftdm_span_set_npi(val, &span->default_caller_data.rdnis.plan); + ftdm_set_npi(val, &span->default_caller_data.rdnis.plan); } else if (!strcasecmp(var, "outbound-bearer_cap")) { - ftdm_span_set_bearer_capability(val, &span->default_caller_data.bearer_capability); + ftdm_set_bearer_capability(val, (uint8_t*)&span->default_caller_data.bearer_capability); } else if (!strcasecmp(var, "outbound-bearer_layer1")) { - ftdm_span_set_bearer_layer1(val, &span->default_caller_data.bearer_layer1); - } else if (!strcasecmp(var, "local-number")) { + ftdm_set_bearer_layer1(val, (uint8_t*)&span->default_caller_data.bearer_layer1); + } else if (!strcasecmp(var, "local-number")) { if (add_local_number(val, span) != FTDM_SUCCESS) { return FTDM_FAIL; } @@ -291,13 +290,9 @@ ftdm_status_t ftmod_isdn_parse_cfg(ftdm_conf_parameter_t *ftdm_parameters, ftdm_ signal_data->facility_timeout = 0; } } else if (!strcasecmp(var, "facility-ie-decode")) { - if (!strcasecmp(val, "yes")) { - signal_data->facility_ie_decode = SNGISDN_OPT_TRUE; - } else if (!strcasecmp(val, "no")) { - signal_data->facility_ie_decode = SNGISDN_OPT_FALSE; - } else { - ftdm_log(FTDM_LOG_ERROR, "Invalid value for parameter:%s:%s\n", var, val); - } + parse_yesno(var, val, &signal_data->facility_ie_decode); + } else if (!strcasecmp(var, "ignore-cause-value")) { + parse_yesno(var, val, &signal_data->ignore_cause_value); } else { ftdm_log(FTDM_LOG_WARNING, "Ignoring unknown parameter %s\n", ftdm_parameters[paramindex].var); } diff --git a/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_stack_hndl.c b/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_stack_hndl.c index a541a655d8..6bf0c25212 100644 --- a/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_stack_hndl.c +++ b/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_stack_hndl.c @@ -127,13 +127,15 @@ void sngisdn_process_con_ind (sngisdn_event_data_t *sngisdn_event) ftdm_channel_add_var(ftdmchan, "isdn_specific_var", "1"); #endif /* Fill in call information */ - get_calling_num(&ftdmchan->caller_data, &conEvnt->cgPtyNmb); - get_called_num(&ftdmchan->caller_data, &conEvnt->cdPtyNmb); - get_redir_num(&ftdmchan->caller_data, &conEvnt->redirNmb); + get_calling_num(ftdmchan, &conEvnt->cgPtyNmb); + get_called_num(ftdmchan, &conEvnt->cdPtyNmb); + get_redir_num(ftdmchan, &conEvnt->redirNmb); + get_calling_subaddr(ftdmchan, &conEvnt->cgPtySad); - if (get_calling_name_from_display(&ftdmchan->caller_data, &conEvnt->display) != FTDM_SUCCESS) { - get_calling_name_from_usr_usr(&ftdmchan->caller_data, &conEvnt->usrUsr); + if (get_calling_name_from_display(ftdmchan, &conEvnt->display) != FTDM_SUCCESS) { + get_calling_name_from_usr_usr(ftdmchan, &conEvnt->usrUsr); } + get_prog_ind_ie(ftdmchan, &conEvnt->progInd); 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); @@ -148,35 +150,35 @@ void sngisdn_process_con_ind (sngisdn_event_data_t *sngisdn_event) snprintf(ftdmchan->caller_data.aniII, 5, "%.2d", conEvnt->ni2OctStr.str.val[3]); } } + } - if (conEvnt->facilityStr.eh.pres) { - if (signal_data->facility_ie_decode == SNGISDN_OPT_FALSE) { - get_facility_ie(&ftdmchan->caller_data, conEvnt->facilityStr.facilityStr.val, conEvnt->facilityStr.facilityStr.len); - } else if (signal_data->facility == SNGISDN_OPT_TRUE) { - /* Verify whether the Caller Name will come in a subsequent FACILITY message */ - uint16_t ret_val; - char retrieved_str[255]; - - ret_val = sng_isdn_retrieve_facility_caller_name(conEvnt->facilityStr.facilityStr.val, conEvnt->facilityStr.facilityStr.len, retrieved_str); - /* - return values for "sng_isdn_retrieve_facility_information_following": - If there will be no information following, or fails to decode IE, returns -1 - If there will be no information following, but current FACILITY IE contains a caller name, returns 0 - If there will be information following, returns 1 - */ + if (conEvnt->facilityStr.eh.pres) { + if (signal_data->facility_ie_decode == SNGISDN_OPT_FALSE) { + get_facility_ie(ftdmchan, &conEvnt->facilityStr); + } else if (signal_data->facility == SNGISDN_OPT_TRUE) { + /* Verify whether the Caller Name will come in a subsequent FACILITY message */ + uint16_t ret_val; + char retrieved_str[255]; - if (ret_val == 1) { - ftdm_log_chan_msg(ftdmchan, FTDM_LOG_DEBUG, "Expecting Caller name in FACILITY\n"); - ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_GET_CALLERID); - /* Launch timer in case we never get a FACILITY msg */ - if (signal_data->facility_timeout) { - ftdm_sched_timer(signal_data->sched, "facility_timeout", signal_data->facility_timeout, - sngisdn_facility_timeout, (void*) sngisdn_info, &sngisdn_info->timers[SNGISDN_TIMER_FACILITY]); - } - break; - } else if (ret_val == 0) { - strcpy(ftdmchan->caller_data.cid_name, retrieved_str); + ret_val = sng_isdn_retrieve_facility_caller_name(conEvnt->facilityStr.facilityStr.val, conEvnt->facilityStr.facilityStr.len, retrieved_str); + /* + return values for "sng_isdn_retrieve_facility_information_following": + If there will be no information following, or fails to decode IE, returns -1 + If there will be no information following, but current FACILITY IE contains a caller name, returns 0 + If there will be information following, returns 1 + */ + + if (ret_val == 1) { + ftdm_log_chan_msg(ftdmchan, FTDM_LOG_DEBUG, "Expecting Caller name in FACILITY\n"); + ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_GET_CALLERID); + /* Launch timer in case we never get a FACILITY msg */ + if (signal_data->facility_timeout) { + ftdm_sched_timer(signal_data->sched, "facility_timeout", signal_data->facility_timeout, + sngisdn_facility_timeout, (void*) sngisdn_info, &sngisdn_info->timers[SNGISDN_TIMER_FACILITY]); } + break; + } else if (ret_val == 0) { + strcpy(ftdmchan->caller_data.cid_name, retrieved_str); } } } @@ -254,8 +256,7 @@ void sngisdn_process_con_cfm (sngisdn_event_data_t *sngisdn_event) ISDN_FUNC_TRACE_ENTER(__FUNCTION__); - /* Function does not require any info from conStEvnt struct for now */ - /* CnStEvnt *cnStEvnt = &sngisdn_event->event.cnStEvnt; */ + CnStEvnt *cnStEvnt = &sngisdn_event->event.cnStEvnt; ftdm_assert(!ftdm_test_flag(ftdmchan, FTDM_CHANNEL_STATE_CHANGE), "State change flag pending\n"); @@ -281,6 +282,7 @@ void sngisdn_process_con_cfm (sngisdn_event_data_t *sngisdn_event) case FTDM_CHANNEL_STATE_PROGRESS: case FTDM_CHANNEL_STATE_PROGRESS_MEDIA: case FTDM_CHANNEL_STATE_DIALING: + get_prog_ind_ie(ftdmchan, &cnStEvnt->progInd); ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_UP); break; case FTDM_CHANNEL_STATE_HANGUP_COMPLETE: @@ -344,9 +346,13 @@ void sngisdn_process_cnst_ind (sngisdn_event_data_t *sngisdn_event) suId, suInstId, spInstId, ces); switch(evntType) { + case MI_CALLPROC: case MI_PROGRESS: - if (signal_data->switchtype == SNGISDN_SWITCH_NI2 && - cnStEvnt->causeDgn[0].eh.pres && cnStEvnt->causeDgn[0].causeVal.pres) { + case MI_ALERTING: + get_prog_ind_ie(ftdmchan, &cnStEvnt->progInd); + + if (signal_data->ignore_cause_value != SNGISDN_OPT_TRUE && + cnStEvnt->causeDgn[0].eh.pres && cnStEvnt->causeDgn[0].causeVal.pres) { switch(cnStEvnt->causeDgn[0].causeVal.val) { case 17: /* User Busy */ @@ -371,24 +377,17 @@ void sngisdn_process_cnst_ind (sngisdn_event_data_t *sngisdn_event) goto sngisdn_process_cnst_ind_end; } } - /* fall-through */ - case MI_ALERTING: - case MI_CALLPROC: - + switch(ftdmchan->state) { case FTDM_CHANNEL_STATE_DIALING: - if (evntType == MI_CALLPROC) { - ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_PROCEED); - } else if (evntType == MI_PROGRESS || - (cnStEvnt->progInd.eh.pres && cnStEvnt->progInd.progDesc.val == IN_PD_IBAVAIL)) { + case FTDM_CHANNEL_STATE_PROCEED: + if (cnStEvnt->progInd.eh.pres && cnStEvnt->progInd.progDesc.val == IN_PD_IBAVAIL) { ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_PROGRESS_MEDIA); } else { ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_PROGRESS); } - break; case FTDM_CHANNEL_STATE_PROGRESS: - if (evntType == MI_PROGRESS || - (cnStEvnt->progInd.eh.pres && cnStEvnt->progInd.progDesc.val == IN_PD_IBAVAIL)) { + if (cnStEvnt->progInd.eh.pres && cnStEvnt->progInd.progDesc.val == IN_PD_IBAVAIL) { ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_PROGRESS_MEDIA); } break; @@ -417,7 +416,7 @@ void sngisdn_process_cnst_ind (sngisdn_event_data_t *sngisdn_event) ftdm_size_t min_digits = ((sngisdn_span_data_t*)ftdmchan->span->signal_data)->min_digits; ftdm_size_t num_digits; - get_called_num(&ftdmchan->caller_data, &cnStEvnt->cdPtyNmb); + get_called_num(ftdmchan, &cnStEvnt->cdPtyNmb); num_digits = strlen(ftdmchan->caller_data.dnis.digits); if (cnStEvnt->sndCmplt.eh.pres || num_digits >= min_digits) { @@ -476,7 +475,7 @@ void sngisdn_process_disc_ind (sngisdn_event_data_t *sngisdn_event) case FTDM_CHANNEL_STATE_UP: if (discEvnt->facilityStr.eh.pres) { if (signal_data->facility_ie_decode == SNGISDN_OPT_FALSE) { - get_facility_ie(&ftdmchan->caller_data, discEvnt->facilityStr.facilityStr.val, discEvnt->facilityStr.facilityStr.len); + get_facility_ie(ftdmchan, &discEvnt->facilityStr); } else { /* Call libsng_isdn facility decode function and copy variables here */ } @@ -573,7 +572,7 @@ void sngisdn_process_rel_ind (sngisdn_event_data_t *sngisdn_event) if (relEvnt->facilityStr.eh.pres) { if (signal_data->facility_ie_decode == SNGISDN_OPT_FALSE) { - get_facility_ie(&ftdmchan->caller_data, relEvnt->facilityStr.facilityStr.val, relEvnt->facilityStr.facilityStr.len); + get_facility_ie(ftdmchan, &relEvnt->facilityStr); } else { /* Call libsng_isdn facility decode function and copy variables here */ } @@ -789,7 +788,7 @@ void sngisdn_process_fac_ind (sngisdn_event_data_t *sngisdn_event) ftdm_sigmsg_t sigev; if (facEvnt->facElmt.facStr.pres) { if (signal_data->facility_ie_decode == SNGISDN_OPT_FALSE) { - get_facility_ie(&ftdmchan->caller_data, &facEvnt->facElmt.facStr.val[2], facEvnt->facElmt.facStr.len); + get_facility_ie_str(ftdmchan, &facEvnt->facElmt.facStr.val[2], facEvnt->facElmt.facStr.len); } else { /* Call libsng_isdn facility decode function and copy variables here */ } diff --git a/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_stack_out.c b/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_stack_out.c index 36c6782a97..e91f21f55e 100644 --- a/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_stack_out.c +++ b/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_stack_out.c @@ -34,13 +34,12 @@ #include "ftmod_sangoma_isdn.h" -static void sngisdn_set_prog_desc(ProgInd *progInd, ftdm_sngisdn_progind_t prod_ind); - void sngisdn_snd_setup(ftdm_channel_t *ftdmchan) { - ConEvnt conEvnt; + ConEvnt conEvnt; sngisdn_chan_data_t *sngisdn_info = ftdmchan->call_data; - sngisdn_span_data_t *signal_data = (sngisdn_span_data_t*) ftdmchan->span->signal_data; + sngisdn_span_data_t *signal_data = (sngisdn_span_data_t*) ftdmchan->span->signal_data; + ftdm_sngisdn_progind_t prog_ind = {SNGISDN_PROGIND_LOC_USER, SNGISDN_PROGIND_DESCR_NETE_ISDN}; ftdm_assert((!sngisdn_info->suInstId && !sngisdn_info->spInstId), "Trying to call out, but call data was not cleared\n"); @@ -118,14 +117,6 @@ void sngisdn_snd_setup(ftdm_channel_t *ftdmchan) conEvnt.chanId.chanNmbSlotMap.val[0] = ftdmchan->physical_chan_id; } - conEvnt.progInd.eh.pres = PRSNT_NODEF; - conEvnt.progInd.location.pres = PRSNT_NODEF; - conEvnt.progInd.location.val = IN_LOC_USER; - conEvnt.progInd.codeStand0.pres = PRSNT_NODEF; - conEvnt.progInd.codeStand0.val = IN_CSTD_CCITT; - conEvnt.progInd.progDesc.pres = PRSNT_NODEF; - conEvnt.progInd.progDesc.val = IN_PD_NOTETEISDN; /* Not end-to-end ISDN */ - if (signal_data->switchtype == SNGISDN_SWITCH_EUROISDN) { conEvnt.sndCmplt.eh.pres = PRSNT_NODEF; } @@ -135,11 +126,13 @@ void sngisdn_snd_setup(ftdm_channel_t *ftdmchan) } ftdm_log_chan(sngisdn_info->ftdmchan, FTDM_LOG_INFO, "Outgoing call: Called No:[%s] Calling No:[%s]\n", ftdmchan->caller_data.dnis.digits, ftdmchan->caller_data.cid_num.digits); - set_called_num(&conEvnt.cdPtyNmb, &ftdmchan->caller_data); - set_calling_num(&conEvnt.cgPtyNmb, &ftdmchan->caller_data); - set_redir_num(&conEvnt.redirNmb, &ftdmchan->caller_data); - set_calling_name(&conEvnt, ftdmchan); + set_called_num(ftdmchan, &conEvnt.cdPtyNmb); + set_calling_num(ftdmchan, &conEvnt.cgPtyNmb); + set_calling_subaddr(ftdmchan, &conEvnt.cgPtySad); + set_redir_num(ftdmchan, &conEvnt.redirNmb); + set_calling_name(ftdmchan, &conEvnt); set_facility_ie(ftdmchan, &conEvnt.facilityStr); + set_prog_ind_ie(ftdmchan, &conEvnt.progInd, prog_ind); ftdm_log_chan(ftdmchan, FTDM_LOG_INFO, "Sending SETUP (suId:%d suInstId:%u spInstId:%u dchan:%d ces:%d)\n", signal_data->cc_id, sngisdn_info->suInstId, sngisdn_info->spInstId, signal_data->dchan_id, sngisdn_info->ces); @@ -347,15 +340,7 @@ void sngisdn_snd_progress(ftdm_channel_t *ftdmchan, ftdm_sngisdn_progind_t prog_ } memset(&cnStEvnt, 0, sizeof(cnStEvnt)); - - cnStEvnt.progInd.eh.pres = PRSNT_NODEF; - cnStEvnt.progInd.location.pres = PRSNT_NODEF; - cnStEvnt.progInd.location.val = IN_LOC_USER; - cnStEvnt.progInd.codeStand0.pres = PRSNT_NODEF; - cnStEvnt.progInd.codeStand0.val = IN_CSTD_CCITT; - cnStEvnt.progInd.progDesc.pres = PRSNT_NODEF; - - sngisdn_set_prog_desc(&cnStEvnt.progInd, prog_ind); + set_prog_ind_ie(ftdmchan, &cnStEvnt.progInd, prog_ind); ftdm_log_chan(ftdmchan, FTDM_LOG_INFO, "Sending PROGRESS (suId:%d suInstId:%u spInstId:%u dchan:%d ces:%d)\n", signal_data->cc_id, sngisdn_info->suInstId, sngisdn_info->spInstId, signal_data->dchan_id, sngisdn_info->ces); if(sng_isdn_con_status(signal_data->cc_id, sngisdn_info->suInstId, sngisdn_info->spInstId,&cnStEvnt, MI_PROGRESS, signal_data->dchan_id, sngisdn_info->ces)) { @@ -380,13 +365,7 @@ void sngisdn_snd_alert(ftdm_channel_t *ftdmchan, ftdm_sngisdn_progind_t prog_ind memset(&cnStEvnt, 0, sizeof(cnStEvnt)); - cnStEvnt.progInd.eh.pres = PRSNT_NODEF; - cnStEvnt.progInd.location.pres = PRSNT_NODEF; - cnStEvnt.progInd.location.val = IN_LOC_USER; - cnStEvnt.progInd.codeStand0.pres = PRSNT_NODEF; - cnStEvnt.progInd.codeStand0.val = IN_CSTD_CCITT; - cnStEvnt.progInd.progDesc.pres = PRSNT_NODEF; - sngisdn_set_prog_desc(&cnStEvnt.progInd, prog_ind); + set_prog_ind_ie(ftdmchan, &cnStEvnt.progInd, prog_ind); ftdm_log_chan(ftdmchan, FTDM_LOG_INFO, "Sending ALERT (suId:%d suInstId:%u spInstId:%u dchan:%d ces:%d)\n", signal_data->cc_id, sngisdn_info->suInstId, sngisdn_info->spInstId, signal_data->dchan_id, sngisdn_info->ces); @@ -398,10 +377,10 @@ void sngisdn_snd_alert(ftdm_channel_t *ftdmchan, ftdm_sngisdn_progind_t prog_ind void sngisdn_snd_connect(ftdm_channel_t *ftdmchan) { - CnStEvnt cnStEvnt; - + CnStEvnt cnStEvnt; sngisdn_chan_data_t *sngisdn_info = (sngisdn_chan_data_t*) ftdmchan->call_data; sngisdn_span_data_t *signal_data = (sngisdn_span_data_t*) ftdmchan->span->signal_data; + ftdm_sngisdn_progind_t prog_ind = {SNGISDN_PROGIND_LOC_USER, SNGISDN_PROGIND_DESCR_NETE_ISDN}; if (!sngisdn_info->suInstId || !sngisdn_info->spInstId) { ftdm_log_chan(ftdmchan, FTDM_LOG_ERROR, "Sending CONNECT, but no call data, aborting (suId:%d suInstId:%u spInstId:%u)\n", signal_data->cc_id, sngisdn_info->suInstId, sngisdn_info->spInstId); @@ -444,14 +423,8 @@ void sngisdn_snd_connect(ftdm_channel_t *ftdmchan) cnStEvnt.chanId.chanNmbSlotMap.len = 1; cnStEvnt.chanId.chanNmbSlotMap.val[0] = ftdmchan->physical_chan_id; } - - cnStEvnt.progInd.eh.pres = PRSNT_NODEF; - cnStEvnt.progInd.location.pres = PRSNT_NODEF; - cnStEvnt.progInd.location.val = IN_LOC_USER; - cnStEvnt.progInd.codeStand0.pres = PRSNT_NODEF; - cnStEvnt.progInd.codeStand0.val = IN_CSTD_CCITT; - cnStEvnt.progInd.progDesc.pres = PRSNT_NODEF; - cnStEvnt.progInd.progDesc.val = IN_PD_NOTETEISDN; /* Not end-to-end ISDN */ + + set_prog_ind_ie(ftdmchan, &cnStEvnt.progInd, prog_ind); ftdm_log_chan(ftdmchan, FTDM_LOG_INFO, "Sending CONNECT (suId:%d suInstId:%u spInstId:%u dchan:%d ces:%d)\n", signal_data->cc_id, sngisdn_info->suInstId, sngisdn_info->spInstId, signal_data->dchan_id, sngisdn_info->ces); if (sng_isdn_con_response(signal_data->cc_id, sngisdn_info->suInstId, sngisdn_info->spInstId, &cnStEvnt, signal_data->dchan_id, sngisdn_info->ces)) { @@ -473,7 +446,12 @@ void sngisdn_snd_fac_req(ftdm_channel_t *ftdmchan) } memset(&facEvnt, 0, sizeof(facEvnt)); - + + set_facility_ie_str(ftdmchan, &facEvnt.facElmt.facStr.val[2], (ftdm_size_t*)&facEvnt.facElmt.facStr.len); + + facEvnt.facElmt.facStr.val[0] = 0x1C; + facEvnt.facElmt.facStr.val[1] = facEvnt.facElmt.facStr.len; + ftdm_log_chan(ftdmchan, FTDM_LOG_INFO, "Sending FACILITY (suId:%d suInstId:%u spInstId:%u dchan:%d ces:%d)\n", signal_data->cc_id, sngisdn_info->suInstId, sngisdn_info->spInstId, signal_data->dchan_id, sngisdn_info->ces); if (sng_isdn_facility_request(signal_data->cc_id, sngisdn_info->suInstId, sngisdn_info->spInstId, &facEvnt, MI_FACIL, signal_data->dchan_id, sngisdn_info->ces)) { @@ -619,32 +597,6 @@ void sngisdn_snd_release(ftdm_channel_t *ftdmchan, uint8_t glare) return; } -static void sngisdn_set_prog_desc(ProgInd *progInd, ftdm_sngisdn_progind_t prog_ind) -{ - switch(prog_ind) { - case SNGISDN_PROGIND_NETE_ISDN: - progInd->progDesc.val = IN_PD_NOTETEISDN; - break; - case SNGISDN_PROGIND_DEST_NISDN: - progInd->progDesc.val = IN_PD_DSTNOTISDN; - break; - case SNGISDN_PROGIND_ORIG_NISDN: - progInd->progDesc.val = IN_PD_ORGNOTISDN; - break; - case SNGISDN_PROGIND_RET_ISDN: - progInd->progDesc.val = IN_PD_CALLRET; - break; - case SNGISDN_PROGIND_SERV_CHANGE: - /* Trillium defines do not match ITU-T Q931 Progress descriptions, - indicate a delayed response for now */ - progInd->progDesc.val = IN_PD_DELRESP; - break; - case SNGISDN_PROGIND_IB_AVAIL: - progInd->progDesc.val = IN_PD_IBAVAIL; - break; - } - return; -} /* We received an incoming frame on the d-channel, send data to the stack */ void sngisdn_snd_data(ftdm_channel_t *dchan, uint8_t *data, ftdm_size_t len) diff --git a/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_support.c b/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_support.c index 4ddb90bbd3..964d06caaf 100644 --- a/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_support.c +++ b/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_support.c @@ -33,6 +33,15 @@ */ #include "ftmod_sangoma_isdn.h" +#define SNGISDN_Q931_FACILITY_IE_ID 0x1C + +/* ftmod_sangoma_isdn specific enum look-up functions */ + +FTDM_ENUM_NAMES(SNGISDN_PROGIND_DESCR_NAMES, SNGISDN_PROGIND_DESCR_STRINGS) +FTDM_STR2ENUM(ftdm_str2ftdm_sngisdn_progind_descr, ftdm_sngisdn_progind_descr2str, ftdm_sngisdn_progind_descr_t, SNGISDN_PROGIND_DESCR_NAMES, SNGISDN_PROGIND_DESCR_INVALID) + +FTDM_ENUM_NAMES(SNGISDN_PROGIND_LOC_NAMES, SNGISDN_PROGIND_LOC_STRINGS) +FTDM_STR2ENUM(ftdm_str2ftdm_sngisdn_progind_loc, ftdm_sngisdn_progind_loc2str, ftdm_sngisdn_progind_loc_t, SNGISDN_PROGIND_LOC_NAMES, SNGISDN_PROGIND_LOC_INVALID) ftdm_status_t sngisdn_check_free_ids(void); @@ -129,7 +138,6 @@ ftdm_status_t get_ftdmchan_by_spInstId(int16_t cc_id, uint32_t spInstId, sngisdn ftdm_status_t sngisdn_set_avail_rate(ftdm_span_t *span, sngisdn_avail_t avail) { - if (span->trunk_type == FTDM_TRUNK_BRI || span->trunk_type == FTDM_TRUNK_BRI_PTMP) { @@ -147,8 +155,9 @@ ftdm_status_t sngisdn_set_avail_rate(ftdm_span_t *span, sngisdn_avail_t avail) return FTDM_SUCCESS; } -ftdm_status_t get_calling_num(ftdm_caller_data_t *caller_data, CgPtyNmb *cgPtyNmb) +ftdm_status_t get_calling_num(ftdm_channel_t *ftdmchan, CgPtyNmb *cgPtyNmb) { + ftdm_caller_data_t *caller_data = &ftdmchan->caller_data; if (cgPtyNmb->eh.pres != PRSNT_NODEF) { return FTDM_FAIL; } @@ -176,8 +185,9 @@ ftdm_status_t get_calling_num(ftdm_caller_data_t *caller_data, CgPtyNmb *cgPtyNm return FTDM_SUCCESS; } -ftdm_status_t get_called_num(ftdm_caller_data_t *caller_data, CdPtyNmb *cdPtyNmb) +ftdm_status_t get_called_num(ftdm_channel_t *ftdmchan, CdPtyNmb *cdPtyNmb) { + ftdm_caller_data_t *caller_data = &ftdmchan->caller_data; if (cdPtyNmb->eh.pres != PRSNT_NODEF) { return FTDM_FAIL; } @@ -199,8 +209,9 @@ ftdm_status_t get_called_num(ftdm_caller_data_t *caller_data, CdPtyNmb *cdPtyNmb return FTDM_SUCCESS; } -ftdm_status_t get_redir_num(ftdm_caller_data_t *caller_data, RedirNmb *redirNmb) +ftdm_status_t get_redir_num(ftdm_channel_t *ftdmchan, RedirNmb *redirNmb) { + ftdm_caller_data_t *caller_data = &ftdmchan->caller_data; if (redirNmb->eh.pres != PRSNT_NODEF) { return FTDM_FAIL; } @@ -219,8 +230,9 @@ ftdm_status_t get_redir_num(ftdm_caller_data_t *caller_data, RedirNmb *redirNmb) return FTDM_SUCCESS; } -ftdm_status_t get_calling_name_from_display(ftdm_caller_data_t *caller_data, Display *display) +ftdm_status_t get_calling_name_from_display(ftdm_channel_t *ftdmchan, Display *display) { + ftdm_caller_data_t *caller_data = &ftdmchan->caller_data; if (display->eh.pres != PRSNT_NODEF) { return FTDM_FAIL; } @@ -232,8 +244,9 @@ ftdm_status_t get_calling_name_from_display(ftdm_caller_data_t *caller_data, Dis return FTDM_SUCCESS; } -ftdm_status_t get_calling_name_from_usr_usr(ftdm_caller_data_t *caller_data, UsrUsr *usrUsr) +ftdm_status_t get_calling_name_from_usr_usr(ftdm_channel_t *ftdmchan, UsrUsr *usrUsr) { + ftdm_caller_data_t *caller_data = &ftdmchan->caller_data; if (usrUsr->eh.pres != PRSNT_NODEF) { return FTDM_FAIL; } @@ -250,26 +263,124 @@ ftdm_status_t get_calling_name_from_usr_usr(ftdm_caller_data_t *caller_data, Usr return FTDM_SUCCESS; } -ftdm_status_t get_facility_ie(ftdm_caller_data_t *caller_data, uint8_t *data, uint32_t data_len) +ftdm_status_t get_calling_subaddr(ftdm_channel_t *ftdmchan, CgPtySad *cgPtySad) { + char subaddress[100]; + + if (cgPtySad->eh.pres != PRSNT_NODEF) { + return FTDM_FAIL; + } + memset(subaddress, 0, sizeof(subaddress)); + if(cgPtySad->sadInfo.len >= sizeof(subaddress)) { + ftdm_log_chan(ftdmchan, FTDM_LOG_WARNING, "Calling Party Subaddress exceeds local size limit (len:%d max:%d)\n", cgPtySad->sadInfo.len, sizeof(subaddress)); + cgPtySad->sadInfo.len = sizeof(subaddress)-1; + } + + memcpy(subaddress, (char*)cgPtySad->sadInfo.val, cgPtySad->sadInfo.len); + subaddress[cgPtySad->sadInfo.len] = '\0'; + ftdm_channel_add_var(ftdmchan, "isdn.calling_subaddr", subaddress); + return FTDM_SUCCESS; +} + +ftdm_status_t get_facility_ie(ftdm_channel_t *ftdmchan, FacilityStr *facilityStr) +{ + if (!facilityStr->eh.pres) { + return FTDM_FAIL; + } + + return get_facility_ie_str(ftdmchan, facilityStr->facilityStr.val, facilityStr->facilityStr.len); +} + +ftdm_status_t get_facility_ie_str(ftdm_channel_t *ftdmchan, uint8_t *data, ftdm_size_t data_len) +{ + ftdm_caller_data_t *caller_data = &ftdmchan->caller_data; if (data_len > sizeof(caller_data->raw_data)-2) { ftdm_log(FTDM_LOG_CRIT, "Length of Facility IE exceeds maximum length\n"); return FTDM_FAIL; } - + memset(caller_data->raw_data, 0, sizeof(caller_data->raw_data)); /* Always include Facility IE identifier + len so this can be used as a sanity check by the user */ - caller_data->raw_data[0] = 0x1C; + caller_data->raw_data[0] = SNGISDN_Q931_FACILITY_IE_ID; caller_data->raw_data[1] = data_len; memcpy(&caller_data->raw_data[2], data, data_len); caller_data->raw_data_len = data_len+2; - return FTDM_SUCCESS; } -ftdm_status_t set_calling_num(CgPtyNmb *cgPtyNmb, ftdm_caller_data_t *caller_data) +ftdm_status_t get_prog_ind_ie(ftdm_channel_t *ftdmchan, ProgInd *progInd) { + uint8_t val; + if (!progInd->eh.pres) { + return FTDM_FAIL; + } + + if (progInd->progDesc.pres) { + switch (progInd->progDesc.val) { + case IN_PD_NOTETEISDN: + val = SNGISDN_PROGIND_DESCR_NETE_ISDN; + break; + case IN_PD_DSTNOTISDN: + val = SNGISDN_PROGIND_DESCR_DEST_NISDN; + break; + case IN_PD_ORGNOTISDN: + val = SNGISDN_PROGIND_DESCR_ORIG_NISDN; + break; + case IN_PD_CALLRET: + val = SNGISDN_PROGIND_DESCR_RET_ISDN; + break; + case IN_PD_DELRESP: + val = SNGISDN_PROGIND_DESCR_SERV_CHANGE; + break; + case IN_PD_IBAVAIL: + val = SNGISDN_PROGIND_DESCR_IB_AVAIL; + break; + default: + ftdm_log_chan(ftdmchan, FTDM_LOG_WARNING, "Unknown Progress Indicator Description (%d)\n", progInd->progDesc.val); + val = SNGISDN_PROGIND_DESCR_INVALID; + break; + } + ftdm_channel_add_var(ftdmchan, "isdn.prog_ind.descr", ftdm_sngisdn_progind_descr2str(val)); + } + + if (progInd->location.pres) { + switch (progInd->location.val) { + case IN_LOC_USER: + val = SNGISDN_PROGIND_LOC_USER; + break; + case IN_LOC_PRIVNETLU: + val = SNGISDN_PROGIND_LOC_PRIV_NET_LOCAL_USR; + break; + case IN_LOC_PUBNETLU: + val = SNGISDN_PROGIND_LOC_PUB_NET_LOCAL_USR; + break; + case IN_LOC_TRANNET: + val = SNGISDN_PROGIND_LOC_TRANSIT_NET; + break; + case IN_LOC_PUBNETRU: + val = SNGISDN_PROGIND_LOC_PUB_NET_REMOTE_USR; + break; + case IN_LOC_PRIVNETRU: + val = SNGISDN_PROGIND_LOC_PRIV_NET_REMOTE_USR; + break; + case IN_LOC_NETINTER: + val = SNGISDN_PROGIND_LOC_NET_BEYOND_INTRW; + break; + default: + ftdm_log_chan(ftdmchan, FTDM_LOG_WARNING, "Unknown Progress Indicator Location (%d)", progInd->location.val); + val = SNGISDN_PROGIND_LOC_INVALID; + break; + } + ftdm_channel_add_var(ftdmchan, "isdn.prog_ind.loc", ftdm_sngisdn_progind_loc2str(val)); + } + return FTDM_SUCCESS; +} + + +ftdm_status_t set_calling_num(ftdm_channel_t *ftdmchan, CgPtyNmb *cgPtyNmb) +{ + ftdm_caller_data_t *caller_data = &ftdmchan->caller_data; uint8_t len = strlen(caller_data->cid_num.digits); if (!len) { return FTDM_SUCCESS; @@ -296,9 +407,11 @@ ftdm_status_t set_calling_num(CgPtyNmb *cgPtyNmb, ftdm_caller_data_t *caller_dat return FTDM_SUCCESS; } -ftdm_status_t set_called_num(CdPtyNmb *cdPtyNmb, ftdm_caller_data_t *caller_data) +ftdm_status_t set_called_num(ftdm_channel_t *ftdmchan, CdPtyNmb *cdPtyNmb) { + ftdm_caller_data_t *caller_data = &ftdmchan->caller_data; uint8_t len = strlen(caller_data->dnis.digits); + if (!len) { return FTDM_SUCCESS; } @@ -326,8 +439,9 @@ ftdm_status_t set_called_num(CdPtyNmb *cdPtyNmb, ftdm_caller_data_t *caller_data return FTDM_SUCCESS; } -ftdm_status_t set_redir_num(RedirNmb *redirNmb, ftdm_caller_data_t *caller_data) +ftdm_status_t set_redir_num(ftdm_channel_t *ftdmchan, RedirNmb *redirNmb) { + ftdm_caller_data_t *caller_data = &ftdmchan->caller_data; uint8_t len = strlen(caller_data->rdnis.digits); if (!len) { return FTDM_SUCCESS; @@ -358,7 +472,7 @@ ftdm_status_t set_redir_num(RedirNmb *redirNmb, ftdm_caller_data_t *caller_data) } -ftdm_status_t set_calling_name(ConEvnt *conEvnt, ftdm_channel_t *ftdmchan) +ftdm_status_t set_calling_name(ftdm_channel_t *ftdmchan, ConEvnt *conEvnt) { uint8_t len; ftdm_caller_data_t *caller_data = &ftdmchan->caller_data; @@ -411,20 +525,139 @@ ftdm_status_t set_calling_name(ConEvnt *conEvnt, ftdm_channel_t *ftdmchan) return FTDM_SUCCESS; } +ftdm_status_t set_calling_subaddr(ftdm_channel_t *ftdmchan, CgPtySad *cgPtySad) +{ + const char* clg_subaddr = NULL; + clg_subaddr = ftdm_channel_get_var(ftdmchan, "isdn.calling_subaddr"); + if ((clg_subaddr != NULL) && (*clg_subaddr)) { + unsigned len = strlen (clg_subaddr); + cgPtySad->eh.pres = PRSNT_NODEF; + cgPtySad->typeSad.pres = 1; + cgPtySad->typeSad.val = 0; /* NSAP */ + cgPtySad->oddEvenInd.pres = 1; + cgPtySad->oddEvenInd.val = 0; + + ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "Sending Calling Party Subaddress:%s\n", clg_subaddr); + cgPtySad->sadInfo.pres = 1; + cgPtySad->sadInfo.len = len; + memcpy(cgPtySad->sadInfo.val, clg_subaddr, len); + } + return FTDM_SUCCESS; +} + + ftdm_status_t set_facility_ie(ftdm_channel_t *ftdmchan, FacilityStr *facilityStr) { - const char *facility_str = NULL; - - facility_str = ftdm_channel_get_var(ftdmchan, "isdn.facility.val"); - if (facility_str) { + ftdm_status_t status; + status = set_facility_ie_str(ftdmchan, facilityStr->facilityStr.val, (ftdm_size_t*)&facilityStr->facilityStr.len); + if (status == FTDM_SUCCESS) { facilityStr->eh.pres = PRSNT_NODEF; - facilityStr->facilityStr.len = strlen(facility_str); - memcpy(facilityStr->facilityStr.val, facility_str, facilityStr->facilityStr.len); - return FTDM_SUCCESS; + facilityStr->facilityStr.pres = PRSNT_NODEF; } + return status; +} + +ftdm_status_t set_facility_ie_str(ftdm_channel_t *ftdmchan, uint8_t *data, ftdm_size_t *data_len) +{ + ftdm_caller_data_t *caller_data = &ftdmchan->caller_data; + + if (caller_data->raw_data_len > 0 && caller_data->raw_data[0] == SNGISDN_Q931_FACILITY_IE_ID) { + + *data_len = caller_data->raw_data[1]; + memcpy(data, &caller_data->raw_data[2], *data_len); + return FTDM_SUCCESS; + } return FTDM_FAIL; } +ftdm_status_t set_prog_ind_ie(ftdm_channel_t *ftdmchan, ProgInd *progInd, ftdm_sngisdn_progind_t prog_ind) +{ + const char *str = NULL; + int descr = prog_ind.descr; + int loc = prog_ind.loc; + + str = ftdm_channel_get_var(ftdmchan, "isdn.prog_ind.descr"); + if (str && *str) { + /* User wants to override progress indicator */ + descr = ftdm_str2ftdm_sngisdn_progind_descr(str); + } + + if (descr == SNGISDN_PROGIND_DESCR_INVALID) { + /* User does not want to send progress indicator */ + return FTDM_SUCCESS; + } + + str = ftdm_channel_get_var(ftdmchan, "isdn.prog_ind.loc"); + if (str && *str) { + loc = ftdm_str2ftdm_sngisdn_progind_loc(str); + } + if (loc == SNGISDN_PROGIND_LOC_INVALID) { + loc = SNGISDN_PROGIND_LOC_USER; + } + + progInd->eh.pres = PRSNT_NODEF; + progInd->codeStand0.pres = PRSNT_NODEF; + progInd->codeStand0.val = IN_CSTD_CCITT; + + progInd->progDesc.pres = PRSNT_NODEF; + switch(descr) { + case SNGISDN_PROGIND_DESCR_NETE_ISDN: + progInd->progDesc.val = IN_PD_NOTETEISDN; + break; + case SNGISDN_PROGIND_DESCR_DEST_NISDN: + progInd->progDesc.val = IN_PD_DSTNOTISDN; + break; + case SNGISDN_PROGIND_DESCR_ORIG_NISDN: + progInd->progDesc.val = IN_PD_ORGNOTISDN; + break; + case SNGISDN_PROGIND_DESCR_RET_ISDN: + progInd->progDesc.val = IN_PD_CALLRET; + break; + case SNGISDN_PROGIND_DESCR_SERV_CHANGE: + /* Trillium defines do not match ITU-T Q931 Progress descriptions, + indicate a delayed response for now */ + progInd->progDesc.val = IN_PD_DELRESP; + break; + case SNGISDN_PROGIND_DESCR_IB_AVAIL: + progInd->progDesc.val = IN_PD_IBAVAIL; + break; + default: + ftdm_log(FTDM_LOG_WARNING, "Invalid prog_ind description:%d\n", descr); + progInd->progDesc.val = IN_PD_NOTETEISDN; + break; + } + + progInd->location.pres = PRSNT_NODEF; + switch (loc) { + case SNGISDN_PROGIND_LOC_USER: + progInd->location.val = IN_LOC_USER; + break; + case SNGISDN_PROGIND_LOC_PRIV_NET_LOCAL_USR: + progInd->location.val = IN_LOC_PRIVNETLU; + break; + case SNGISDN_PROGIND_LOC_PUB_NET_LOCAL_USR: + progInd->location.val = IN_LOC_PUBNETLU; + break; + case SNGISDN_PROGIND_LOC_TRANSIT_NET: + progInd->location.val = IN_LOC_TRANNET; + break; + case SNGISDN_PROGIND_LOC_PUB_NET_REMOTE_USR: + progInd->location.val = IN_LOC_PUBNETRU; + break; + case SNGISDN_PROGIND_LOC_PRIV_NET_REMOTE_USR: + progInd->location.val = IN_LOC_PRIVNETRU; + break; + case SNGISDN_PROGIND_LOC_NET_BEYOND_INTRW: + progInd->location.val = IN_LOC_NETINTER; + break; + default: + ftdm_log(FTDM_LOG_WARNING, "Invalid prog_ind location:%d\n", loc); + progInd->location.val = IN_PD_NOTETEISDN; + } + return FTDM_SUCCESS; +} + + void sngisdn_t3_timeout(void* p_sngisdn_info) { sngisdn_chan_data_t *sngisdn_info = (sngisdn_chan_data_t*)p_sngisdn_info; @@ -581,13 +814,12 @@ uint8_t sngisdn_get_infoTranCap_from_stack(ftdm_bearer_cap_t bearer_capability) switch(bearer_capability) { case FTDM_BEARER_CAP_SPEECH: return IN_ITC_SPEECH; - case FTDM_BEARER_CAP_64K_UNRESTRICTED: return IN_ITC_UNRDIG; - case FTDM_BEARER_CAP_3_1KHZ_AUDIO: return IN_ITC_A31KHZ; - + 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 */ } return FTDM_BEARER_CAP_SPEECH; @@ -598,13 +830,12 @@ uint8_t sngisdn_get_usrInfoLyr1Prot_from_stack(ftdm_user_layer1_prot_t layer1_pr switch(layer1_prot) { case FTDM_USER_LAYER1_PROT_V110: return IN_UIL1_CCITTV110; - case FTDM_USER_LAYER1_PROT_ULAW: return IN_UIL1_G711ULAW; - case FTDM_USER_LAYER1_PROT_ALAW: return IN_UIL1_G711ALAW; - + 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 */ } return IN_UIL1_G711ULAW; diff --git a/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_trace.c b/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_trace.c index 624d35c147..e5167164b3 100644 --- a/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_trace.c +++ b/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_trace.c @@ -613,6 +613,21 @@ uint32_t sngisdn_decode_ie(char *str, uint32_t *str_len, uint8_t current_codeset return 0; break; case PROT_Q931_IE_CALLED_PARTY_SUBADDRESS: + { + uint8_t type; + uint8_t currentOct, j=0; + char calling_subaddr_string[82]; + memset(calling_subaddr_string, 0, sizeof(calling_subaddr_string)); + type = get_bits(OCTET(3),5,7); + currentOct = 3; + while(currentOct++ <= len+1) { + calling_subaddr_string[j++]=ia5[get_bits(OCTET(currentOct),1,4)][get_bits(OCTET(currentOct),5,8)]; + } + calling_subaddr_string[j++]='\0'; + *str_len += sprintf(&str[*str_len], "%s (l:%d) type:%s(%d) \n", + calling_subaddr_string, (j-1), get_code_2_str(type, dcodQ931TypeOfSubaddressTable), type); + } + break; case PROT_Q931_IE_REDIRECTION_NUMBER: case PROT_Q931_IE_NOTIFICATION_IND: case PROT_Q931_IE_DATE_TIME: diff --git a/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_trace.h b/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_trace.h index d210c50db9..f054de9377 100644 --- a/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_trace.h +++ b/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_trace.h @@ -544,5 +544,11 @@ struct code2str dcodQ931GenDigitsTypeTable[] = { {-1, "Invalid"}, }; +struct code2str dcodQ931TypeOfSubaddressTable[] = { + { 0x00, "NSAP"}, + { 0x02, "User-specified"}, + { -1, "Invalid"}, +}; + #endif /* __FTMOD_SANGOMA_ISDN_TRACE_H__ */ diff --git a/libs/freetdm/src/include/freetdm.h b/libs/freetdm/src/include/freetdm.h index 014eeef852..45254e817f 100644 --- a/libs/freetdm/src/include/freetdm.h +++ b/libs/freetdm/src/include/freetdm.h @@ -41,6 +41,7 @@ #include "ftdm_declare.h" +#include "ftdm_call_utils.h" /*! \brief Max number of channels per physical span */ #define FTDM_MAX_CHANNELS_PHYSICAL_SPAN 32 @@ -62,23 +63,6 @@ #define FTDM_INVALID_INT_PARM 0xFF -/*! \brief FreeTDM APIs possible return codes */ -typedef enum { - FTDM_SUCCESS, /*!< Success */ - FTDM_FAIL, /*!< Failure, generic error return code, use ftdm_channel_get_last_error or ftdm_span_get_last_error for details */ - FTDM_MEMERR, /*!< Memory error, most likely allocation failure */ - FTDM_TIMEOUT, /*!< Operation timed out (ie: polling on a device)*/ - FTDM_NOTIMPL, /*!< Operation not implemented */ - FTDM_BREAK, /*!< Request the caller to perform a break (context-dependant, ie: stop getting DNIS/ANI) */ - FTDM_EINVAL /*!< Invalid argument */ -} ftdm_status_t; - -/*! \brief FreeTDM bool type. */ -typedef enum { - FTDM_FALSE, - FTDM_TRUE -} ftdm_bool_t; - /*! \brief Thread/Mutex OS abstraction API. */ #include "ftdm_os.h" @@ -220,8 +204,10 @@ typedef enum { FTDM_TON_SUBSCRIBER_NUMBER, FTDM_TON_ABBREVIATED_NUMBER, FTDM_TON_RESERVED, - FTDM_TON_INVALID = 255 + FTDM_TON_INVALID } ftdm_ton_t; +#define TON_STRINGS "unknown", "international", "national", "network-specific", "subscriber-number", "abbreviated-number", "reserved", "invalid" +FTDM_STR2ENUM_P(ftdm_str2ftdm_ton, ftdm_ton2str, ftdm_ton_t) /*! Numbering Plan Identification (NPI) */ typedef enum { @@ -232,8 +218,52 @@ typedef enum { FTDM_NPI_NATIONAL = 8, FTDM_NPI_PRIVATE = 9, FTDM_NPI_RESERVED = 10, - FTDM_NPI_INVALID = 255 + FTDM_NPI_INVALID } ftdm_npi_t; +#define NPI_STRINGS "unknown", "ISDN", "data", "telex", "national", "private", "reserved", "invalid" +FTDM_STR2ENUM_P(ftdm_str2ftdm_npi, ftdm_npi2str, ftdm_npi_t) + +/*! Presentation Ind */ +typedef enum { + FTDM_PRES_ALLOWED, + FTDM_PRES_RESTRICTED, + FTDM_PRES_NOT_AVAILABLE, + FTDM_PRES_RESERVED, + FTDM_PRES_INVALID +} ftdm_presentation_t; +#define PRESENTATION_STRINGS "presentation-allowed", "presentation-restricted", "number-not-available", "reserved", "Invalid" +FTDM_STR2ENUM_P(ftdm_str2ftdm_presentation, ftdm_presentation2str, ftdm_presentation_t) + +/*! Screening Ind */ +typedef enum { + FTDM_SCREENING_NOT_SCREENED, + FTDM_SCREENING_VERIFIED_PASSED, + FTDM_SCREENING_VERIFIED_FAILED, + FTDM_SCREENING_NETWORK_PROVIDED, + FTDM_SCREENING_INVALID +} ftdm_screening_t; +#define SCREENING_STRINGS "user-provided-not-screened", "user-provided-verified-and-passed", "user-provided-verified-and-failed", "network-provided", "invalid" +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_INVALID +} ftdm_bearer_cap_t; +#define BEARER_CAP_STRINGS "speech", "unrestricted-digital-information", "3.1-Khz-audio", "invalid" +FTDM_STR2ENUM_P(ftdm_str2ftdm_bearer_cap, ftdm_bearer_cap2str, ftdm_bearer_cap_t) + +/*! \brief user information layer 1 protocol */ +typedef enum { + FTDM_USER_LAYER1_PROT_V110 = 0x01, + FTDM_USER_LAYER1_PROT_ULAW = 0x02, + FTDM_USER_LAYER1_PROT_ALAW = 0x03, + FTDM_USER_LAYER1_PROT_INVALID +} ftdm_user_layer1_prot_t; +#define USER_LAYER1_PROT_STRINGS "V.110", "u-law", "a-law", "Invalid" +FTDM_STR2ENUM_P(ftdm_str2ftdm_usr_layer1_prot, ftdm_user_layer1_prot2str, ftdm_user_layer1_prot_t) /*! \brief Number abstraction */ typedef struct { @@ -242,20 +272,6 @@ typedef struct { uint8_t plan; } ftdm_number_t; -/*! \brief bearer capability */ -typedef enum { - FTDM_BEARER_CAP_SPEECH = 0x00, - FTDM_BEARER_CAP_64K_UNRESTRICTED = 0x02, - FTDM_BEARER_CAP_3_1KHZ_AUDIO = 0x03 -} ftdm_bearer_cap_t; - -/*! \brief user information layer 1 protocol */ -typedef enum { - FTDM_USER_LAYER1_PROT_V110 = 0x01, - FTDM_USER_LAYER1_PROT_ULAW = 0x02, - FTDM_USER_LAYER1_PROT_ALAW = 0x03, -} ftdm_user_layer1_prot_t; - /*! \brief Caller information */ typedef struct ftdm_caller_data { char cid_date[8]; /*!< Caller ID date */ diff --git a/libs/freetdm/src/include/ftdm_call_utils.h b/libs/freetdm/src/include/ftdm_call_utils.h new file mode 100644 index 0000000000..835a5c6cdc --- /dev/null +++ b/libs/freetdm/src/include/ftdm_call_utils.h @@ -0,0 +1,118 @@ +/* + * Copyright (c) 2010, Sangoma Technologies + * David Yat Sin + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * * Neither the name of the original author; nor the names of any contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER + * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef __FTDM_CALL_UTILS_H__ +#define __FTDM_CALL_UTILS_H__ + +/*! + * \brief Set the Numbering Plan Identification from a string + * + * \param npi_string string value + * \param target the target to set value to + * + * \retval FTDM_SUCCESS success + * \retval FTDM_FAIL failure + */ +FT_DECLARE(ftdm_status_t) ftdm_set_npi(const char *npi_string, uint8_t *target); + + +/*! + * \brief Set the Type of number from a string + * + * \param ton_string string value + * \param target the target to set value to + * + * \retval FTDM_SUCCESS success + * \retval FTDM_FAIL failure + */ +FT_DECLARE(ftdm_status_t) ftdm_set_ton(const char *ton_string, uint8_t *target); + +/*! + * \brief Set the Bearer Capability from a string + * + * \param bc_string string value + * \param target the target to set value to + * + * \retval FTDM_SUCCESS success + * \retval FTDM_FAIL failure + */ +FT_DECLARE(ftdm_status_t) ftdm_set_bearer_capability(const char *bc_string, uint8_t *target); + +/*! + * \brief Set the Bearer Capability - Layer 1 from a string + * + * \param bc_string string value + * \param target the target to set value to + * + * \retval FTDM_SUCCESS success + * \retval FTDM_FAIL failure + */ +FT_DECLARE(ftdm_status_t) ftdm_set_bearer_layer1(const char *bc_string, uint8_t *target); + +/*! + * \brief Set the Screening Ind from a string + * + * \param screen_string string value + * \param target the target to set value to + * + * \retval FTDM_SUCCESS success + * \retval FTDM_FAIL failure + */ +FT_DECLARE(ftdm_status_t) ftdm_set_screening_ind(const char *string, uint8_t *target); + + +/*! + * \brief Set the Presentation Ind from an enum + * + * \param screen_string string value + * \param target the target to set value to + * + * \retval FTDM_SUCCESS success + * \retval FTDM_FAIL failure + */ +FT_DECLARE(ftdm_status_t) ftdm_set_presentation_ind(const char *string, uint8_t *target); + + +/*! + * \brief Checks whether a string contains only numbers + * + * \param number string value + * + * \retval FTDM_SUCCESS success + * \retval FTDM_FAIL failure + */ +FT_DECLARE(ftdm_status_t) ftdm_is_number(const char *number); + +#endif /* __FTDM_CALL_UTILS_H__ */ + diff --git a/libs/freetdm/src/include/ftdm_declare.h b/libs/freetdm/src/include/ftdm_declare.h index ab3b5c8966..4aba703f28 100644 --- a/libs/freetdm/src/include/ftdm_declare.h +++ b/libs/freetdm/src/include/ftdm_declare.h @@ -171,6 +171,23 @@ typedef int ftdm_socket_t; #include #endif +/*! \brief FreeTDM APIs possible return codes */ +typedef enum { + FTDM_SUCCESS, /*!< Success */ + FTDM_FAIL, /*!< Failure, generic error return code, use ftdm_channel_get_last_error or ftdm_span_get_last_error for details */ + FTDM_MEMERR, /*!< Memory error, most likely allocation failure */ + FTDM_TIMEOUT, /*!< Operation timed out (ie: polling on a device)*/ + FTDM_NOTIMPL, /*!< Operation not implemented */ + FTDM_BREAK, /*!< Request the caller to perform a break (context-dependant, ie: stop getting DNIS/ANI) */ + FTDM_EINVAL /*!< Invalid argument */ +} ftdm_status_t; + +/*! \brief FreeTDM bool type. */ +typedef enum { + FTDM_FALSE, + FTDM_TRUE +} ftdm_bool_t; + /*! * \brief FreeTDM channel. * This is the basic data structure used to place calls and I/O operations diff --git a/libs/freetdm/src/include/private/ftdm_call_utils.h b/libs/freetdm/src/include/private/ftdm_call_utils.h deleted file mode 100644 index 782abde927..0000000000 --- a/libs/freetdm/src/include/private/ftdm_call_utils.h +++ /dev/null @@ -1,47 +0,0 @@ -/* - * Copyright (c) 2010, Sangoma Technologies - * David Yat Sin - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * * Neither the name of the original author; nor the names of any contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER - * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef __FTDM_CALL_UTILS_H__ -#define __FTDM_CALL_UTILS_H__ - -#include "freetdm.h" - -FT_DECLARE(ftdm_status_t) ftdm_span_set_npi(const char *npi_string, uint8_t *target); -FT_DECLARE(ftdm_status_t) ftdm_span_set_ton(const char *ton_string, uint8_t *target); -FT_DECLARE(ftdm_status_t) ftdm_span_set_bearer_capability(const char *bc_string, ftdm_bearer_cap_t *target); -FT_DECLARE(ftdm_status_t) ftdm_span_set_bearer_layer1(const char *bc_string, ftdm_user_layer1_prot_t *target); -FT_DECLARE(ftdm_status_t) ftdm_is_number(char *number); - -#endif /* __FTDM_CALL_UTILS_H__ */ -