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);
+
/******************************************************************************/
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 */
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
{
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));
break;
}
- int i = 0;
-
while (ftdmchan->caller_data.cid_num.digits[i] != '\0') {
i++;
}
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 */
} 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)) */
/**************************************************************************/
}
- /* 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);
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;
uint32_t flags;
sngss7_glare_data_t glare;
sngss7_timer_data_t t35;
+ sngss7_group_data_t grs;
}sngss7_chan_data_t;
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),
/******************************************************************************/
/* 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 *********************************************************************/