diff --git a/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_in.c b/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_in.c index 2ca7fff739..3298d86ac0 100644 --- a/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_in.c +++ b/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_in.c @@ -70,6 +70,8 @@ static ftdm_status_t handle_blo_rsp(uint32_t suInstId, uint32_t spInstId, uint32 static ftdm_status_t handle_ubl_req(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, uint8_t globalFlg, uint8_t evntType, SiStaEvnt *siStaEvnt); static ftdm_status_t handle_ubl_rsp(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, uint8_t globalFlg, uint8_t evntType, SiStaEvnt *siStaEvnt); +static ftdm_status_t handle_grs_req(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, uint8_t globalFlg, uint8_t evntType, SiStaEvnt *siStaEvnt); + /******************************************************************************/ @@ -701,7 +703,7 @@ void sngss7_sta_ind(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, uint break; /**************************************************************************/ case SIT_STA_GRSREQ: /* circuit group reset request */ - SS7_WARN(" %s indication not currently supported\n", DECODE_LCC_EVENT(evntType)); + handle_grs_req(suInstId, spInstId, circuit, globalFlg, evntType, siStaEvnt); break; /**************************************************************************/ case SIT_STA_CIRUNEQPD: /* circuit unequipped indication */ @@ -1413,6 +1415,64 @@ static ftdm_status_t handle_ubl_rsp(uint32_t suInstId, uint32_t spInstId, uint32 return FTDM_SUCCESS; } +/******************************************************************************/ +static ftdm_status_t handle_grs_req(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, uint8_t globalFlg, uint8_t evntType, SiStaEvnt *siStaEvnt) +{ + SS7_FUNC_TRACE_ENTER(__FUNCTION__); + + sngss7_chan_data_t *sngss7_info = NULL; + ftdm_channel_t *ftdmchan = NULL; + int range; + int x; + + /* extract the range value from the event structure */ + if ((siStaEvnt->rangStat.eh.pres == PRSNT_NODEF) && (siStaEvnt->rangStat.range.pres == PRSNT_NODEF)) { + range = siStaEvnt->rangStat.range.val; + } else { + SS7_ERROR("Received GRS with no range value on CIC = %d\n", sngss7_info->circuit->cic); + SS7_FUNC_TRACE_EXIT(__FUNCTION__); + return FTDM_FAIL; + } + + /* loop over the cics starting from circuit until range+1 */ + for (x = circuit; x < (circuit + range + 1); x++) { + /* grab the circuit in question */ + if (extract_chan_data(circuit, &sngss7_info, &ftdmchan)) { + SS7_ERROR("Failed to extract channel data for circuit = %d!\n", circuit); + /* konrad fix me */ + } + + /* now that we have the right channel...put a lock on it so no-one else can use it */ + ftdm_mutex_lock(ftdmchan->mutex); + + /* check if there is a pending state change, give it a bit to clear */ + if (check_for_state_change(ftdmchan)) { + SS7_ERROR("Failed to wait for pending state change on CIC = %d\n", sngss7_info->circuit->cic); + ftdm_mutex_unlock(ftdmchan->mutex); + /* konrad fix me */ + }; + + /* store the circuit and range into the sngss7 info so that we can figure out when to send GRA */ + sngss7_info->grs.circuit = circuit; + sngss7_info->grs.range = range; + sngss7_info->globalFlg = globalFlg; + + /* flag the channel as having received a reset */ + sngss7_set_flag(sngss7_info, FLAG_GRP_RESET_RX); + + /* throw the channel into RESTART state */ + ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_RESTART); + + /* unlock the channel again before we exit */ + ftdm_mutex_unlock(ftdmchan->mutex); + + } + + SS7_FUNC_TRACE_EXIT(__FUNCTION__); + return FTDM_SUCCESS; +} + + /******************************************************************************/ #if 0 { diff --git a/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_main.c b/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_main.c index dab1b83cd1..a9dad15ae9 100644 --- a/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_main.c +++ b/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_main.c @@ -300,6 +300,9 @@ static void ftdm_sangoma_ss7_process_state_change(ftdm_channel_t *ftdmchan) ftdm_sigmsg_t sigev; ftdm_signaling_status_t status; sngss7_chan_data_t *sngss7_info = ftdmchan->call_data; + sngss7_chan_data_t *tmp_ss7info = NULL; + ftdm_channel_t *tmp_chan = NULL; + int i = 0; memset(&sigev, 0, sizeof(sigev)); @@ -325,8 +328,6 @@ static void ftdm_sangoma_ss7_process_state_change(ftdm_channel_t *ftdmchan) break; } - int i = 0; - while (ftdmchan->caller_data.cid_num.digits[i] != '\0') { i++; } @@ -587,6 +588,28 @@ static void ftdm_sangoma_ss7_process_state_change(ftdm_channel_t *ftdmchan) ftdm_span_send_signal(ftdmchan->span, &sigev); } + /* check if there was a GRS that needs a GRA */ + if (sngss7_test_flag(sngss7_info, FLAG_GRP_RESET_RX)) { + /* check all the circuits in the range to see if we are the last ckt to reset */ + for (i = sngss7_info->grs.circuit; i < (sngss7_info->grs.range + 1); i++) { + if (g_ftdm_sngss7_data.cfg.isupCircuit[i].siglink == 0) { + /* extract the sngss7_info for the circuit */ + tmp_ss7info = g_ftdm_sngss7_data.cfg.isupCircuit[i].obj; + tmp_chan = tmp_ss7info->ftdmchan; + /* check if the circuit is done going through reset */ /* KONRAD FIX ME...better way to check this??? */ + if (!(tmp_chan->state == FTDM_CHANNEL_STATE_DOWN) && (sngss7_test_flag(tmp_ss7info, FLAG_GRP_RESET_RX))) { + /* exit the for loop since we found a circuit still in reset */ + continue; + } /* if inreset */ + } /* if not siglink */ + } /* for */ + + /* if we got through the whole range send out a GRA */ + if (i == (sngss7_info->grs.range + 1)) { + ft_to_sngss7_gra(ftdmchan); + } + } + /* check if we got the reset response */ if (sngss7_test_flag(sngss7_info, FLAG_RESET_TX)) { /* inform Ftdm that the "sig" is up now for this channel */ @@ -666,7 +689,7 @@ static void ftdm_sangoma_ss7_process_state_change(ftdm_channel_t *ftdmchan) } else { /* check if this an incoming RSC */ - if (sngss7_test_flag(sngss7_info, FLAG_RESET_RX)) { + if (sngss7_test_flag(sngss7_info, FLAG_RESET_RX) || sngss7_test_flag(sngss7_info, FLAG_GRP_RESET_RX)) { /* go to a down state to clear the channel and send RSCa */ ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_DOWN); } /* if (sngss7_test_flag(sngss7_info, FLAG_RESET_RX)) */ @@ -910,9 +933,6 @@ static FIO_CHANNEL_OUTGOING_CALL_FUNCTION(ftdm_sangoma_ss7_outgoing_call) /**************************************************************************/ } - /* we should not get to this here...all exit points above use goto */ - SS7_ERROR("WE SHOULD NOT HERE HERE!!!!\n"); - SS7_DEBUG("Call Request on span=%d, chan=%d failed\n"); /* unlock the channel */ ftdm_mutex_unlock(ftdmchan->mutex); diff --git a/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_main.h b/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_main.h index 5f4aacada1..15e2bba314 100644 --- a/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_main.h +++ b/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_main.h @@ -96,6 +96,11 @@ typedef struct sngss7_glare_data { SiConEvnt iam; }sngss7_glare_data_t; +typedef struct sngss7_group_data { + uint32_t circuit; + uint32_t range; +}sngss7_group_data_t; + typedef struct sngss7_chan_data { ftdm_channel_t *ftdmchan; sng_isupCircuit_t *circuit; @@ -106,6 +111,7 @@ typedef struct sngss7_chan_data { uint32_t flags; sngss7_glare_data_t glare; sngss7_timer_data_t t35; + sngss7_group_data_t grs; }sngss7_chan_data_t; @@ -113,9 +119,11 @@ typedef struct sngss7_chan_data { typedef enum { FLAG_RESET_RX = (1 << 0), FLAG_RESET_TX = (1 << 1), - FLAG_REMOTE_REL = (1 << 2), - FLAG_LOCAL_REL = (1 << 3), - FLAG_GLARE = (1 << 4), + FLAG_GRP_RESET_RX = (1 << 2), + FLAG_GRP_RESET_TX = (1 << 3), + FLAG_REMOTE_REL = (1 << 4), + FLAG_LOCAL_REL = (1 << 5), + FLAG_GLARE = (1 << 6), FLAG_INFID_RESUME = (1 << 17), FLAG_INFID_PAUSED = (1 << 18), FLAG_CKT_MN_BLOCK_RX = (1 << 19), @@ -140,51 +148,52 @@ extern ftdm_sched_t *sngss7_sched; /******************************************************************************/ /* PROTOTYPES *****************************************************************/ -extern void handle_sng_log(uint8_t level, char *fmt,...); -extern void handle_sng_alarm(sng_alrm_t t_alarm); +void handle_sng_log(uint8_t level, char *fmt,...); +void handle_sng_alarm(sng_alrm_t t_alarm); -extern int ft_to_sngss7_cfg(void); -extern int ft_to_sngss7_activate_all(void); +int ft_to_sngss7_cfg(void); +int ft_to_sngss7_activate_all(void); -extern void ft_to_sngss7_iam(ftdm_channel_t *ftdmchan); -extern void ft_to_sngss7_acm(ftdm_channel_t *ftdmchan); -extern void ft_to_sngss7_anm(ftdm_channel_t *ftdmchan); -extern void ft_to_sngss7_rel(ftdm_channel_t *ftdmchan); -extern void ft_to_sngss7_rlc(ftdm_channel_t *ftdmchan); -extern void ft_to_sngss7_rsc(ftdm_channel_t *ftdmchan); -extern void ft_to_sngss7_rsca(ftdm_channel_t *ftdmchan); -extern void ft_to_sngss7_blo(ftdm_channel_t *ftdmchan); -extern void ft_to_sngss7_bla(ftdm_channel_t *ftdmchan); -extern void ft_to_sngss7_ubl(ftdm_channel_t *ftdmchan); -extern void ft_to_sngss7_uba(ftdm_channel_t *ftdmchan); -extern void ft_to_sngss7_lpa(ftdm_channel_t *ftdmchan); +void ft_to_sngss7_iam(ftdm_channel_t *ftdmchan); +void ft_to_sngss7_acm(ftdm_channel_t *ftdmchan); +void ft_to_sngss7_anm(ftdm_channel_t *ftdmchan); +void ft_to_sngss7_rel(ftdm_channel_t *ftdmchan); +void ft_to_sngss7_rlc(ftdm_channel_t *ftdmchan); +void ft_to_sngss7_rsc(ftdm_channel_t *ftdmchan); +void ft_to_sngss7_rsca(ftdm_channel_t *ftdmchan); +void ft_to_sngss7_blo(ftdm_channel_t *ftdmchan); +void ft_to_sngss7_bla(ftdm_channel_t *ftdmchan); +void ft_to_sngss7_ubl(ftdm_channel_t *ftdmchan); +void ft_to_sngss7_uba(ftdm_channel_t *ftdmchan); +void ft_to_sngss7_lpa(ftdm_channel_t *ftdmchan); +void ft_to_sngss7_gra(ftdm_channel_t *ftdmchan); -extern void sngss7_sta_ind(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, uint8_t globalFlg, uint8_t evntType, SiStaEvnt *siStaEvnt); -extern void sngss7_con_ind(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, SiConEvnt *siConEvnt); -extern void sngss7_con_cfm(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, SiConEvnt *siConEvnt); -extern void sngss7_con_sta(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, SiCnStEvnt *siCnStEvnt, uint8_t evntType); -extern void sngss7_rel_ind(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, SiRelEvnt *siRelEvnt); -extern void sngss7_rel_cfm(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, SiRelEvnt *siRelEvnt); -extern void sngss7_dat_ind(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, SiInfoEvnt *siInfoEvnt); -extern void sngss7_fac_ind(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, uint8_t evntType, SiFacEvnt *siFacEvnt); -extern void sngss7_fac_cfm(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, uint8_t evntType, SiFacEvnt *siFacEvnt); -extern void sngss7_sta_ind(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, uint8_t globalFlg, uint8_t evntType, SiStaEvnt *siStaEvnt); -extern void sngss7_umsg_ind(uint32_t suInstId, uint32_t spInstId, uint32_t circuit); +void sngss7_sta_ind(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, uint8_t globalFlg, uint8_t evntType, SiStaEvnt *siStaEvnt); +void sngss7_con_ind(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, SiConEvnt *siConEvnt); +void sngss7_con_cfm(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, SiConEvnt *siConEvnt); +void sngss7_con_sta(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, SiCnStEvnt *siCnStEvnt, uint8_t evntType); +void sngss7_rel_ind(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, SiRelEvnt *siRelEvnt); +void sngss7_rel_cfm(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, SiRelEvnt *siRelEvnt); +void sngss7_dat_ind(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, SiInfoEvnt *siInfoEvnt); +void sngss7_fac_ind(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, uint8_t evntType, SiFacEvnt *siFacEvnt); +void sngss7_fac_cfm(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, uint8_t evntType, SiFacEvnt *siFacEvnt); +void sngss7_sta_ind(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, uint8_t globalFlg, uint8_t evntType, SiStaEvnt *siStaEvnt); +void sngss7_umsg_ind(uint32_t suInstId, uint32_t spInstId, uint32_t circuit); -extern uint8_t copy_cgPtyNum_from_sngss7(ftdm_caller_data_t *ftdm, SiCgPtyNum *cgPtyNum); -extern uint8_t copy_cgPtyNum_to_sngss7(ftdm_caller_data_t *ftdm, SiCgPtyNum *cgPtyNum); -extern uint8_t copy_cdPtyNum_from_sngss7(ftdm_caller_data_t *ftdm, SiCdPtyNum *cdPtyNum); -extern uint8_t copy_cdPtyNum_to_sngss7(ftdm_caller_data_t *ftdm, SiCdPtyNum *cdPtyNum); -extern uint8_t copy_tknStr_from_sngss7(TknStr str, char *ftdm, TknU8 oddEven); -extern int check_for_state_change(ftdm_channel_t *ftdmchan); -extern ftdm_status_t extract_chan_data(uint32_t circuit, sngss7_chan_data_t **sngss7_info, ftdm_channel_t **ftdmchan); -extern unsigned long get_unique_id(void); +uint8_t copy_cgPtyNum_from_sngss7(ftdm_caller_data_t *ftdm, SiCgPtyNum *cgPtyNum); +uint8_t copy_cgPtyNum_to_sngss7(ftdm_caller_data_t *ftdm, SiCgPtyNum *cgPtyNum); +uint8_t copy_cdPtyNum_from_sngss7(ftdm_caller_data_t *ftdm, SiCdPtyNum *cdPtyNum); +uint8_t copy_cdPtyNum_to_sngss7(ftdm_caller_data_t *ftdm, SiCdPtyNum *cdPtyNum); +uint8_t copy_tknStr_from_sngss7(TknStr str, char *ftdm, TknU8 oddEven); +int check_for_state_change(ftdm_channel_t *ftdmchan); +ftdm_status_t extract_chan_data(uint32_t circuit, sngss7_chan_data_t **sngss7_info, ftdm_channel_t **ftdmchan); +unsigned long get_unique_id(void); -extern int ftmod_ss7_parse_xml(ftdm_conf_parameter_t *ftdm_parameters, ftdm_span_t *span); +int ftmod_ss7_parse_xml(ftdm_conf_parameter_t *ftdm_parameters, ftdm_span_t *span); -extern void handle_isup_t35(void *userdata); +void handle_isup_t35(void *userdata); -extern ftdm_status_t ftdm_sngss7_handle_cli_cmd(ftdm_stream_handle_t *stream, const char *data); +ftdm_status_t ftdm_sngss7_handle_cli_cmd(ftdm_stream_handle_t *stream, const char *data); /******************************************************************************/ /* MACROS *********************************************************************/ diff --git a/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_out.c b/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_out.c index c592933647..edaf36d644 100644 --- a/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_out.c +++ b/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_out.c @@ -58,6 +58,7 @@ void ft_to_sngss7_uba(ftdm_channel_t *ftdmchan); void ft_to_sngss7_lpa(ftdm_channel_t *ftdmchan); +void ft_to_sngss7_gra(ftdm_channel_t *ftdmchan); /* FUNCTIONS ******************************************************************/ void ft_to_sngss7_iam(ftdm_channel_t *ftdmchan) { @@ -404,6 +405,30 @@ void ft_to_sngss7_lpa(ftdm_channel_t *ftdmchan) SS7_FUNC_TRACE_EXIT(__FUNCTION__); return; } + +/******************************************************************************/ +void ft_to_sngss7_gra(ftdm_channel_t *ftdmchan) +{ + SS7_FUNC_TRACE_ENTER(__FUNCTION__); + + sngss7_chan_data_t *sngss7_info = ftdmchan->call_data; + + /* get the original channel the message came in on */ + sngss7_info = g_ftdm_sngss7_data.cfg.isupCircuit[sngss7_info->grs.circuit].obj; + + sng_cc_sta_request(1, + 0, + 0, + sngss7_info->circuit->id, + sngss7_info->globalFlg, + SIT_STA_GRSRSP, + NULL); + + SS7_MSG_TRACE("Transmitted GRA on CIC # %d\n", sngss7_info->circuit->cic); + + SS7_FUNC_TRACE_EXIT(__FUNCTION__); + return; +} /******************************************************************************/ /* For Emacs: * Local Variables: