From 37139badf7870590f5ae62598798547c7368c7a7 Mon Sep 17 00:00:00 2001 From: Konrad Hammel Date: Thu, 10 Mar 2011 15:35:09 -0500 Subject: [PATCH] chlog: freetdm: ss7 - more work on relay stability --- .../ftmod_sangoma_ss7/ftmod_sangoma_ss7_cli.c | 12 +- .../ftmod_sangoma_ss7_cntrl.c | 32 ++++ .../ftmod_sangoma_ss7_handle.c | 13 +- .../ftmod_sangoma_ss7/ftmod_sangoma_ss7_in.c | 98 ++++++++++-- .../ftmod_sangoma_ss7_main.c | 55 +++---- .../ftmod_sangoma_ss7_main.h | 44 +++++- .../ftmod_sangoma_ss7_relay.c | 62 ++++++-- .../ftmod_sangoma_ss7_support.c | 142 +++++++++++++++++- 8 files changed, 387 insertions(+), 71 deletions(-) diff --git a/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_cli.c b/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_cli.c index f8b12ea588..2cd3a13e30 100644 --- a/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_cli.c +++ b/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_cli.c @@ -1011,6 +1011,15 @@ static ftdm_status_t handle_show_flags(ftdm_stream_handle_t *stream, int span, i } } + for (bit = 0; bit < 33; bit++) { + if (ss7_info->blk_flags & ( 0x1 << bit)) { + stream->write_function(stream, "|"); + flag = bit; + text = ftmod_ss7_blk_flag2str(flag); + stream->write_function(stream, "%s",text); + } + } + stream->write_function(stream, "\n"); } /* if ( span and chan) */ @@ -1172,7 +1181,8 @@ static ftdm_status_t handle_show_status(ftdm_stream_handle_t *stream, int span, ftdm_channel_state2str(ftdmchan->state)); if ((sngss7_test_ckt_blk_flag(ss7_info, FLAG_CKT_MN_BLOCK_TX)) || - (sngss7_test_ckt_blk_flag(ss7_info, FLAG_GRP_MN_BLOCK_TX))) { + (sngss7_test_ckt_blk_flag(ss7_info, FLAG_GRP_MN_BLOCK_TX)) || + (sngss7_test_ckt_blk_flag(ss7_info, FLAG_CKT_LC_BLOCK_RX))) { stream->write_function(stream, "l_mn=Y|"); }else { stream->write_function(stream, "l_mn=N|"); diff --git a/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_cntrl.c b/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_cntrl.c index 83ef5e0a42..8a7b095675 100644 --- a/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_cntrl.c +++ b/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_cntrl.c @@ -76,6 +76,7 @@ int ftmod_ss7_enable_grp_mtp3Link(uint32_t procId); int ftmod_ss7_disable_grp_mtp2Link(uint32_t procId); int ftmod_ss7_block_isup_ckt(uint32_t cktId); +int ftmod_ss7_unblock_isup_ckt(uint32_t cktId); /******************************************************************************/ /* FUNCTIONS ******************************************************************/ @@ -875,6 +876,37 @@ int ftmod_ss7_block_isup_ckt(uint32_t cktId) return (sng_cntrl_isup(&pst, &cntrl)); } +/******************************************************************************/ +int ftmod_ss7_unblock_isup_ckt(uint32_t cktId) +{ + SiMngmt cntrl; + Pst pst; + + /* initalize the post structure */ + smPstInit(&pst); + + /* insert the destination Entity */ + pst.dstEnt = ENTSI; + + /* initalize the control structure */ + memset(&cntrl, 0x0, sizeof(SiMngmt)); + + /* initalize the control header */ + smHdrInit(&cntrl.hdr); + + cntrl.hdr.msgType = TCNTRL; /* this is a control request */ + cntrl.hdr.entId.ent = ENTSI; + cntrl.hdr.entId.inst = S_INST; + cntrl.hdr.elmId.elmnt = STICIR; + + cntrl.t.cntrl.s.siElmnt.elmntId.circuit = cktId; + cntrl.t.cntrl.s.siElmnt.elmntParam.cir.flag = LSI_CNTRL_CIR_FORCE; + + cntrl.t.cntrl.action = AENA; /* unblock via UBL */ + cntrl.t.cntrl.subAction = SAELMNT; /* specificed element */ + + return (sng_cntrl_isup(&pst, &cntrl)); +} /******************************************************************************/ /* For Emacs: * Local Variables: diff --git a/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_handle.c b/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_handle.c index e0b6ae08c0..3981cd6597 100644 --- a/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_handle.c +++ b/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_handle.c @@ -1183,7 +1183,7 @@ ftdm_status_t handle_pause(uint32_t suInstId, uint32_t spInstId, uint32_t circui sngss7_set_ckt_flag(sngss7_info, FLAG_INFID_PAUSED); /* clear the resume flag on the channel */ - sngss7_set_ckt_flag(sngss7_info, FLAG_INFID_RESUME); + sngss7_clear_ckt_flag(sngss7_info, FLAG_INFID_RESUME); } /* unlock the channel again before we exit */ @@ -1565,9 +1565,6 @@ ftdm_status_t handle_ubl_req(uint32_t suInstId, uint32_t spInstId, uint32_t circ /* throw the unblock flag */ sngss7_set_ckt_blk_flag(sngss7_info, FLAG_CKT_MN_UNBLK_RX); - /* clear the block flag */ - sngss7_clear_ckt_blk_flag(sngss7_info, FLAG_CKT_MN_BLOCK_RX); - /* set the channel to suspended state */ ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_SUSPENDED); @@ -2017,12 +2014,12 @@ ftdm_status_t handle_local_ubl(uint32_t suInstId, uint32_t spInstId, uint32_t ci /* lock the channel */ ftdm_mutex_lock(ftdmchan->mutex); - /* check if the circuit is already blocked or not */ - if (sngss7_test_ckt_blk_flag(sngss7_info, FLAG_CKT_LC_UNBLK_RX)) { - SS7_WARN("Received local UBL on circuit that is already unblocked!\n"); + /* check if the circuit is blocked or not */ + if (!sngss7_test_ckt_blk_flag(sngss7_info, FLAG_CKT_LC_BLOCK_RX)) { + SS7_WARN("Received local UBL on circuit that is not blocked!\n"); } - /* throw the ckt block flag */ + /* throw the ckt unblock flag */ sngss7_set_ckt_blk_flag(sngss7_info, FLAG_CKT_LC_UNBLK_RX); /* set the channel to suspended state */ 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 76984b907b..f143c20eb9 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 @@ -66,6 +66,12 @@ void sngss7_con_ind(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, SiCo ftdm_channel_t *ftdmchan = NULL; sngss7_event_data_t *sngss7_event = NULL; + if (g_ftdm_sngss7_data.cfg.isupCkt[circuit].type != VOICE) { + SS7_ERROR("Rx sig event on circuit that is not a voice CIC (%d)\n", circuit); + SS7_FUNC_TRACE_EXIT(__FUNCTION__); + return; + } + /* get the ftdmchan and ss7_chan_data from the circuit */ if (extract_chan_data(circuit, &sngss7_info, &ftdmchan)) { SS7_ERROR("Failed to extract channel data for circuit = %d!\n", circuit); @@ -104,6 +110,12 @@ void sngss7_con_cfm(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, SiCo ftdm_channel_t *ftdmchan = NULL; sngss7_event_data_t *sngss7_event = NULL; + if (g_ftdm_sngss7_data.cfg.isupCkt[circuit].type != VOICE) { + SS7_ERROR("Rx sig event on circuit that is not a voice CIC (%d)\n", circuit); + SS7_FUNC_TRACE_EXIT(__FUNCTION__); + return; + } + /* get the ftdmchan and ss7_chan_data from the circuit */ if (extract_chan_data(circuit, &sngss7_info, &ftdmchan)) { SS7_ERROR("Failed to extract channel data for circuit = %d!\n", circuit); @@ -142,6 +154,12 @@ void sngss7_con_sta(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, SiCn ftdm_channel_t *ftdmchan = NULL; sngss7_event_data_t *sngss7_event = NULL; + if (g_ftdm_sngss7_data.cfg.isupCkt[circuit].type != VOICE) { + SS7_ERROR("Rx sig event on circuit that is not a voice CIC (%d)\n", circuit); + SS7_FUNC_TRACE_EXIT(__FUNCTION__); + return; + } + /* get the ftdmchan and ss7_chan_data from the circuit */ if (extract_chan_data(circuit, &sngss7_info, &ftdmchan)) { SS7_ERROR("Failed to extract channel data for circuit = %d!\n", circuit); @@ -181,6 +199,12 @@ void sngss7_rel_ind(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, SiRe ftdm_channel_t *ftdmchan = NULL; sngss7_event_data_t *sngss7_event = NULL; + if (g_ftdm_sngss7_data.cfg.isupCkt[circuit].type != VOICE) { + SS7_ERROR("Rx sig event on circuit that is not a voice CIC (%d)\n", circuit); + SS7_FUNC_TRACE_EXIT(__FUNCTION__); + return; + } + /* get the ftdmchan and ss7_chan_data from the circuit */ if (extract_chan_data(circuit, &sngss7_info, &ftdmchan)) { SS7_ERROR("Failed to extract channel data for circuit = %d!\n", circuit); @@ -219,6 +243,12 @@ void sngss7_rel_cfm(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, SiRe ftdm_channel_t *ftdmchan = NULL; sngss7_event_data_t *sngss7_event = NULL; + if (g_ftdm_sngss7_data.cfg.isupCkt[circuit].type != VOICE) { + SS7_ERROR("Rx sig event on circuit that is not a voice CIC (%d)\n", circuit); + SS7_FUNC_TRACE_EXIT(__FUNCTION__); + return; + } + /* get the ftdmchan and ss7_chan_data from the circuit */ if (extract_chan_data(circuit, &sngss7_info, &ftdmchan)) { SS7_ERROR("Failed to extract channel data for circuit = %d!\n", circuit); @@ -257,6 +287,12 @@ void sngss7_dat_ind(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, SiIn ftdm_channel_t *ftdmchan = NULL; sngss7_event_data_t *sngss7_event = NULL; + if (g_ftdm_sngss7_data.cfg.isupCkt[circuit].type != VOICE) { + SS7_ERROR("Rx sig event on circuit that is not a voice CIC (%d)\n", circuit); + SS7_FUNC_TRACE_EXIT(__FUNCTION__); + return; + } + /* get the ftdmchan and ss7_chan_data from the circuit */ if (extract_chan_data(circuit, &sngss7_info, &ftdmchan)) { SS7_ERROR("Failed to extract channel data for circuit = %d!\n", circuit); @@ -295,6 +331,12 @@ void sngss7_fac_ind(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, uint ftdm_channel_t *ftdmchan = NULL; sngss7_event_data_t *sngss7_event = NULL; + if (g_ftdm_sngss7_data.cfg.isupCkt[circuit].type != VOICE) { + SS7_ERROR("Rx sig event on circuit that is not a voice CIC (%d)\n", circuit); + SS7_FUNC_TRACE_EXIT(__FUNCTION__); + return; + } + /* get the ftdmchan and ss7_chan_data from the circuit */ if (extract_chan_data(circuit, &sngss7_info, &ftdmchan)) { SS7_ERROR("Failed to extract channel data for circuit = %d!\n", circuit); @@ -334,6 +376,12 @@ void sngss7_fac_cfm(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, uint ftdm_channel_t *ftdmchan = NULL; sngss7_event_data_t *sngss7_event = NULL; + if (g_ftdm_sngss7_data.cfg.isupCkt[circuit].type != VOICE) { + SS7_ERROR("Rx sig event on circuit that is not a voice CIC (%d)\n", circuit); + SS7_FUNC_TRACE_EXIT(__FUNCTION__); + return; + } + /* get the ftdmchan and ss7_chan_data from the circuit */ if (extract_chan_data(circuit, &sngss7_info, &ftdmchan)) { SS7_ERROR("Failed to extract channel data for circuit = %d!\n", circuit); @@ -373,6 +421,12 @@ void sngss7_umsg_ind(uint32_t suInstId, uint32_t spInstId, uint32_t circuit) ftdm_channel_t *ftdmchan = NULL; sngss7_event_data_t *sngss7_event = NULL; + if (g_ftdm_sngss7_data.cfg.isupCkt[circuit].type != VOICE) { + SS7_ERROR("Rx sig event on circuit that is not a voice CIC (%d)\n", circuit); + SS7_FUNC_TRACE_EXIT(__FUNCTION__); + return; + } + /* get the ftdmchan and ss7_chan_data from the circuit */ if (extract_chan_data(circuit, &sngss7_info, &ftdmchan)) { SS7_ERROR("Failed to extract channel data for circuit = %d!\n", circuit); @@ -417,21 +471,10 @@ void sngss7_sta_ind(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, uint /**************************************************************************/ case (SIT_STA_PAUSEIND): case (SIT_STA_RESUMEIND): - - /* the circuit for this type of event may not exist on the local system - * so first check if the circuit is local - */ - if ((circuit >= (g_ftdm_sngss7_data.cfg.procId * 1000)) && - (circuit < ((g_ftdm_sngss7_data.cfg.procId +1) * 1000))) { - - /* the circuit is on the local system, handle normally */ - goto sta_ind_local; - } - - /* the circuit is not local, so find a local circuit with the same intfId - * by finding the orginial circuit in our array first, finding the intfId - * from there, then go through the local circuits to see if we find a - * match and use that circuit instead + /* the circuit may or may not be on the local system so we have to find + * circuit with the same intfId. The circuit specified might also be + * a non-voice cic so we also need to find the first voice cic on this + * system with the same intfId. */ intfId = g_ftdm_sngss7_data.cfg.isupCkt[circuit].infId; @@ -444,6 +487,10 @@ void sngss7_sta_ind(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, uint /* compare the intfIds */ if (g_ftdm_sngss7_data.cfg.isupCkt[x].infId == intfId) { + if (g_ftdm_sngss7_data.cfg.isupCkt[circuit].type == VOICE) { + + } + /* we have a match, setup the pointers to the correct values */ circuit = x; @@ -472,7 +519,14 @@ move_along: break; /**************************************************************************/ default: -sta_ind_local: + if (g_ftdm_sngss7_data.cfg.isupCkt[circuit].type != VOICE) { + SS7_ERROR("Rx %s on circuit that is not a voice CIC (%d)\n", + DECODE_LCC_EVENT(evntType), + g_ftdm_sngss7_data.cfg.isupCkt[circuit].cic); + SS7_FUNC_TRACE_EXIT(__FUNCTION__); + return; + } + /* get the ftdmchan and ss7_chan_data from the circuit */ if (extract_chan_data(circuit, &sngss7_info, &ftdmchan)) { SS7_ERROR("Failed to extract channel data for circuit = %d!\n", circuit); @@ -520,6 +574,12 @@ void sngss7_susp_ind(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, SiS ftdm_channel_t *ftdmchan = NULL; sngss7_event_data_t *sngss7_event = NULL; + if (g_ftdm_sngss7_data.cfg.isupCkt[circuit].type != VOICE) { + SS7_ERROR("Rx sig event on circuit that is not a voice CIC (%d)\n", circuit); + SS7_FUNC_TRACE_EXIT(__FUNCTION__); + return; + } + /* get the ftdmchan and ss7_chan_data from the circuit */ if (extract_chan_data(circuit, &sngss7_info, &ftdmchan)) { SS7_ERROR("Failed to extract channel data for circuit = %d!\n", circuit); @@ -561,6 +621,12 @@ void sngss7_resm_ind(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, SiR ftdm_channel_t *ftdmchan = NULL; sngss7_event_data_t *sngss7_event = NULL; + if (g_ftdm_sngss7_data.cfg.isupCkt[circuit].type != VOICE) { + SS7_ERROR("Rx sig event on circuit that is not a voice CIC (%d)\n", circuit); + SS7_FUNC_TRACE_EXIT(__FUNCTION__); + return; + } + /* get the ftdmchan and ss7_chan_data from the circuit */ if (extract_chan_data(circuit, &sngss7_info, &ftdmchan)) { SS7_ERROR("Failed to extract channel data for circuit = %d!\n", circuit); 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 7b885102b9..46bc53ec57 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 @@ -909,8 +909,8 @@ ftdm_status_t ftdm_sangoma_ss7_process_state_change (ftdm_channel_t * ftdmchan) case FTDM_CHANNEL_STATE_RESTART: /* CICs needs a Reset */ if (sngss7_test_ckt_blk_flag(sngss7_info, FLAG_CKT_UCIC_BLOCK)) { - if ((sngss7_test_ckt_blk_flag(sngss7_info, FLAG_RESET_RX)) || - (sngss7_test_ckt_blk_flag(sngss7_info, FLAG_GRP_RESET_RX))) { + if ((sngss7_test_ckt_flag(sngss7_info, FLAG_RESET_RX)) || + (sngss7_test_ckt_flag(sngss7_info, FLAG_GRP_RESET_RX))) { SS7_DEBUG_CHAN(ftdmchan,"Incoming Reset request on CIC in UCIC block, removing UCIC block%s\n", ""); @@ -1020,10 +1020,13 @@ ftdm_status_t ftdm_sangoma_ss7_process_state_change (ftdm_channel_t * ftdmchan) /**************************************************************************/ case FTDM_CHANNEL_STATE_SUSPENDED: /* circuit has been blocked */ - SS7_DEBUG_CHAN(ftdmchan,"Current flags: 0x%X\n", sngss7_info->ckt_flags); + SS7_DEBUG_CHAN(ftdmchan,"Current flags: ckt=0x%X, blk=0x%X\n", + sngss7_info->ckt_flags, + sngss7_info->blk_flags); /**********************************************************************/ if (sngss7_test_ckt_flag(sngss7_info, FLAG_INFID_RESUME)) { + SS7_DEBUG_CHAN(ftdmchan, "Processing RESUME%s\n", ""); /* clear the RESUME flag */ @@ -1038,27 +1041,23 @@ ftdm_status_t ftdm_sangoma_ss7_process_state_change (ftdm_channel_t * ftdmchan) (sngss7_test_ckt_flag (sngss7_info, FLAG_GRP_RESET_TX)) || (sngss7_test_ckt_flag (sngss7_info, FLAG_GRP_RESET_RX))) { - /* go back to the reset state */ + /* don't bring up the sig status but also move to reset */ goto suspend_goto_restart; } else { - /* bring the sig status back up */ sngss7_set_sig_status(sngss7_info, FTDM_SIG_STATE_UP); } - - /* go back to the last state */ - goto suspend_goto_last; } /* if (sngss7_test_flag(sngss7_info, FLAG_INFID_RESUME)) */ - if (sngss7_test_ckt_flag(sngss7_info, FLAG_INFID_PAUSED)) { + if ((sngss7_test_ckt_flag(sngss7_info, FLAG_INFID_PAUSED)) && + (ftdm_test_flag(ftdmchan, FTDM_CHANNEL_SIG_UP))) { + SS7_DEBUG_CHAN(ftdmchan, "Processing PAUSE%s\n", ""); /* bring the sig status down */ sngss7_set_sig_status(sngss7_info, FTDM_SIG_STATE_DOWN); - - /* go back to the last state */ - goto suspend_goto_last; } /* if (sngss7_test_ckt_flag(sngss7_info, FLAG_INFID_PAUSED)) { */ + /**********************************************************************/ if (sngss7_test_ckt_blk_flag(sngss7_info, FLAG_CKT_MN_BLOCK_RX) && !sngss7_test_ckt_blk_flag(sngss7_info, FLAG_CKT_MN_BLOCK_RX_DN)) { @@ -1081,6 +1080,10 @@ ftdm_status_t ftdm_sangoma_ss7_process_state_change (ftdm_channel_t * ftdmchan) !sngss7_test_ckt_blk_flag (sngss7_info, FLAG_CKT_MN_UNBLK_RX_DN)){ SS7_DEBUG_CHAN(ftdmchan, "Processing CKT_MN_UNBLK_RX flag %s\n", ""); + /* clear the block flags */ + sngss7_clear_ckt_blk_flag(sngss7_info, FLAG_CKT_MN_BLOCK_RX); + sngss7_clear_ckt_blk_flag(sngss7_info, FLAG_CKT_MN_BLOCK_RX_DN); + /* clear the unblock flag */ sngss7_clear_ckt_blk_flag (sngss7_info, FLAG_CKT_MN_UNBLK_RX); @@ -1090,9 +1093,6 @@ ftdm_status_t ftdm_sangoma_ss7_process_state_change (ftdm_channel_t * ftdmchan) /* send a uba */ ft_to_sngss7_uba (ftdmchan); - /* throw the done flag */ - sngss7_set_ckt_blk_flag(sngss7_info, FLAG_CKT_MN_UNBLK_RX_DN); - /* check the last state and return to it to allow the call to finish */ goto suspend_goto_last; } @@ -1119,8 +1119,12 @@ ftdm_status_t ftdm_sangoma_ss7_process_state_change (ftdm_channel_t * ftdmchan) !sngss7_test_ckt_blk_flag (sngss7_info, FLAG_CKT_MN_UNBLK_TX_DN)){ SS7_DEBUG_CHAN(ftdmchan, "Processing CKT_MN_UNBLK_TX flag %s\n", ""); + /* clear the block flags */ + sngss7_clear_ckt_blk_flag (sngss7_info, FLAG_CKT_MN_BLOCK_TX); + sngss7_clear_ckt_blk_flag (sngss7_info, FLAG_CKT_MN_BLOCK_TX_DN); + /* clear the unblock flag */ - sngss7_clear_ckt_blk_flag (sngss7_info, FLAG_CKT_MN_UNBLK_TX); + sngss7_clear_ckt_blk_flag(sngss7_info, FLAG_CKT_MN_UNBLK_TX); /* bring the sig status up */ sngss7_set_sig_status(sngss7_info, FTDM_SIG_STATE_UP); @@ -1128,9 +1132,6 @@ ftdm_status_t ftdm_sangoma_ss7_process_state_change (ftdm_channel_t * ftdmchan) /* send a ubl */ ft_to_sngss7_ubl (ftdmchan); - /* throw the done flag */ - sngss7_set_ckt_blk_flag(sngss7_info, FLAG_CKT_MN_UNBLK_TX_DN); - /* check the last state and return to it to allow the call to finish */ goto suspend_goto_last; } @@ -1153,15 +1154,17 @@ ftdm_status_t ftdm_sangoma_ss7_process_state_change (ftdm_channel_t * ftdmchan) if (sngss7_test_ckt_blk_flag(sngss7_info, FLAG_CKT_LC_UNBLK_RX) && !sngss7_test_ckt_blk_flag(sngss7_info, FLAG_CKT_LC_UNBLK_RX_DN)) { SS7_DEBUG_CHAN(ftdmchan, "Processing CKT_LC_UNBLK_RX flag %s\n", ""); + + /* clear the block flags */ + sngss7_clear_ckt_blk_flag (sngss7_info, FLAG_CKT_LC_BLOCK_RX); + sngss7_clear_ckt_blk_flag (sngss7_info, FLAG_CKT_LC_BLOCK_RX_DN); /* clear the unblock flag */ - sngss7_clear_ckt_blk_flag(sngss7_info, FLAG_CKT_MN_UNBLK_RX); + sngss7_clear_ckt_blk_flag(sngss7_info, FLAG_CKT_LC_UNBLK_RX); /* send a uba */ /*ft_to_sngss7_uba(ftdmchan);*/ - /* throw the done flag */ - sngss7_set_ckt_blk_flag(sngss7_info, FLAG_CKT_LC_UNBLK_RX_DN); /* check the last state and return to it to allow the call to finish */ goto suspend_goto_last; @@ -1191,10 +1194,11 @@ ftdm_status_t ftdm_sangoma_ss7_process_state_change (ftdm_channel_t * ftdmchan) if (sngss7_test_ckt_blk_flag (sngss7_info, FLAG_CKT_UCIC_UNBLK) && !sngss7_test_ckt_blk_flag (sngss7_info, FLAG_CKT_UCIC_UNBLK_DN)) { - SS7_DEBUG_CHAN(ftdmchan, "Processing CKT_UCIC_UNBLK flag %s\n", "");; + SS7_DEBUG_CHAN(ftdmchan, "Processing CKT_UCIC_UNBLK flag %s\n", ""); /* remove the UCIC block flag */ sngss7_clear_ckt_blk_flag(sngss7_info, FLAG_CKT_UCIC_BLOCK); + sngss7_clear_ckt_blk_flag(sngss7_info, FLAG_CKT_UCIC_BLOCK_DN); /* remove the UCIC unblock flag */ sngss7_clear_ckt_blk_flag(sngss7_info, FLAG_CKT_UCIC_UNBLK); @@ -1202,13 +1206,12 @@ ftdm_status_t ftdm_sangoma_ss7_process_state_change (ftdm_channel_t * ftdmchan) /* throw the channel into reset to sync states */ sngss7_set_ckt_flag(sngss7_info, FLAG_RESET_TX); - /* throw the done flag */ - sngss7_set_ckt_blk_flag(sngss7_info, FLAG_CKT_UCIC_UNBLK_DN); - /* bring the channel into restart again */ goto suspend_goto_restart; } + SS7_ERROR_CHAN(ftdmchan,"No block flag processed!%s\n", ""); + suspend_goto_last: state_flag = 0; ftdm_set_state(ftdmchan, ftdmchan->last_state); 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 02c450b94a..df8b086c49 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 @@ -560,6 +560,41 @@ typedef enum { FLAG_GRP_MN_UNBLK_TX_DN = (1 << 27) } sng_ckt_block_flag_t; +#define BLK_FLAGS_STRING \ + "UCIC BLK", \ + "UCIC BLK DN", \ + "UCIC UNBLK", \ + "UCIC UNBLK DN", \ + "RX LC BLK", \ + "RX LC BLK DN", \ + "RX LC UNBLK", \ + "RX LC UNBLK DN", \ + "RX CKT BLK", \ + "RX CKT BLK DN", \ + "RX CKT UNBLK", \ + "RX CKT UNBLK DN", \ + "TX CKT BLK", \ + "TX CKT BLK DN", \ + "TX CKT UNBLK", \ + "TX CKT UNBLK DN", \ + "RX GRP MN BLK", \ + "RX GRP MN BLK DN", \ + "RX GRP MN UNBLK", \ + "RX GRP MN UNBLK DN", \ + "TX GRP MN BLK", \ + "TX GRP MN BLK DN", \ + "TX GRP MN UNBLK", \ + "TX GRP MN UNBLK DN", \ + "RX GRP HW BLK", \ + "RX GRP HW BLK DN", \ + "RX GRP HW UNBLK", \ + "RX GRP HW UNBLK DN", \ + "TX GRP HW BLK", \ + "TX GRP HW BLK DN", \ + "TX GRP HW UNBLK", \ + "TX GRP HW UNBLK DN" +FTDM_STR2ENUM_P(ftmod_ss7_blk_state2flag, ftmod_ss7_blk_flag2str, sng_ckt_block_flag_t) + /* valid for every cfg array except circuits */ typedef enum { SNGSS7_CONFIGURED = (1 << 0), @@ -656,7 +691,7 @@ int ftmod_ss7_enable_grp_mtp3Link(uint32_t procId); int ftmod_ss7_disable_grp_mtp2Link(uint32_t procId); int ftmod_ss7_block_isup_ckt(uint32_t cktId); - +int ftmod_ss7_unblock_isup_ckt(uint32_t cktId); /* in ftmod_sangoma_ss7_sta.c */ @@ -795,6 +830,13 @@ void handle_isup_t35(void *userdata); /******************************************************************************/ /* MACROS *********************************************************************/ +#define SS7_STATE_CHANGE(ftdmchan, new_state) \ +if (ftdmchan->state == new_state) { \ + ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_IDLE); \ +} else { \ + ftdm_set_state(ftdmchan, new_state); \ +} + #define SS7_DEBUG(a,...) ftdm_log(FTDM_LOG_DEBUG,a , ##__VA_ARGS__ ); #define SS7_INFO(a,...) ftdm_log(FTDM_LOG_INFO,a , ##__VA_ARGS__ ); #define SS7_WARN(a,...) ftdm_log(FTDM_LOG_WARNING,a , ##__VA_ARGS__ ); diff --git a/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_relay.c b/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_relay.c index d34d62c217..1af538d727 100644 --- a/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_relay.c +++ b/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_relay.c @@ -45,10 +45,11 @@ ftdm_status_t handle_relay_connect(RyMngmt *sta); ftdm_status_t handle_relay_disconnect(RyMngmt *sta); -static ftdm_status_t enable_all_ckts_for_relay(void); +/*static ftdm_status_t enable_all_ckts_for_relay(void);*/ static ftdm_status_t reconfig_all_ckts_for_relay(void); static ftdm_status_t disable_all_ckts_for_relay(void); static ftdm_status_t block_all_ckts_for_relay(uint32_t procId); +static ftdm_status_t unblock_all_ckts_for_relay(uint32_t procId); static ftdm_status_t disable_all_sigs_for_relay(uint32_t procId); static ftdm_status_t disble_all_mtp2_sigs_for_relay(void); /******************************************************************************/ @@ -72,26 +73,20 @@ ftdm_status_t handle_relay_connect(RyMngmt *sta) switch (sng_relay->type) { /******************************************************************/ case (LRY_CT_TCP_CLIENT): - /* check the status of all isup intfs in case we weren't connected when - * the interface became active - */ - check_status_of_all_isup_intf(); - /* reconfigure all ISUP ckts, since the main system would have lost all configs */ if (reconfig_all_ckts_for_relay()) { SS7_ERROR("Failed to reconfigure ISUP Ckts!\n"); /* we're done....this is very bad! */ - } else { - /* if the circuits reconfiged then bring then back up */ - enable_all_ckts_for_relay(); } - break; /******************************************************************/ case (LRY_CT_TCP_SERVER): - /*unblock_all_ckts_for_relay(sta->t.usta.s.ryErrUsta.errPid);*/ + /* bring the sig links on the client system back up */ ftmod_ss7_enable_grp_mtp3Link(sta->t.usta.s.ryUpUsta.id); - + + /* unbloock the ckts on the client system */ + unblock_all_ckts_for_relay(sta->t.usta.s.ryUpUsta.id); + break; /******************************************************************/ default: @@ -179,7 +174,7 @@ ftdm_status_t disable_all_ckts_for_relay(void) return FTDM_SUCCESS; } - +#if 0 /******************************************************************************/ ftdm_status_t enable_all_ckts_for_relay(void) { @@ -227,7 +222,7 @@ ftdm_status_t enable_all_ckts_for_relay(void) return FTDM_SUCCESS; } - +#endif /******************************************************************************/ ftdm_status_t reconfig_all_ckts_for_relay(void) { @@ -244,6 +239,9 @@ ftdm_status_t reconfig_all_ckts_for_relay(void) /* mark the circuit for re-configuration */ sngss7_set_ckt_flag(sngss7_info, FLAG_CKT_RECONFIG); + + /* clear the relay flag */ + sngss7_clear_ckt_flag(sngss7_info, FLAG_RELAY_DOWN); } /* move to the next circuit */ @@ -312,6 +310,42 @@ ftdm_status_t disble_all_mtp2_sigs_for_relay(void) } +/******************************************************************************/ +static ftdm_status_t unblock_all_ckts_for_relay(uint32_t procId) +{ + int x; + int ret; + + /* we just got connection to this procId, send out a unblock for all these circuits + * since we blocked them when we lost the connection + */ + x = (procId * 1000) + 1; + while (g_ftdm_sngss7_data.cfg.isupCkt[x].id != 0) { + /**************************************************************************/ + if (g_ftdm_sngss7_data.cfg.isupCkt[x].type == VOICE) { + + /* send a block request via stack manager */ + ret = ftmod_ss7_unblock_isup_ckt(g_ftdm_sngss7_data.cfg.isupCkt[x].id); + if (ret) { + SS7_INFO("Successfully unblocked CIC:%d(ckt:%d) due to Relay connection\n", + g_ftdm_sngss7_data.cfg.isupCkt[x].cic, + g_ftdm_sngss7_data.cfg.isupCkt[x].id); + } else { + SS7_ERROR("Failed to unblock CIC:%d(ckt:%d) due to Relay connection\n", + g_ftdm_sngss7_data.cfg.isupCkt[x].cic, + g_ftdm_sngss7_data.cfg.isupCkt[x].id); + } + + } /* if (g_ftdm_sngss7_data.cfg.isupCkt[x].type == VOICE) */ + + /* move along */ + x++; + /**************************************************************************/ + } /* while (g_ftdm_sngss7_data.cfg.isupCkt[x].id != 0) */ + + return FTDM_SUCCESS; +} + /******************************************************************************/ /* For Emacs: * Local Variables: diff --git a/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_support.c b/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_support.c index ded695c205..2b915b1053 100644 --- a/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_support.c +++ b/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_support.c @@ -94,6 +94,9 @@ ftdm_status_t sngss7_add_raw_data(sngss7_chan_data_t *sngss7_info, uint8_t* data FTDM_ENUM_NAMES(CKT_FLAGS_NAMES, CKT_FLAGS_STRING) FTDM_STR2ENUM(ftmod_ss7_ckt_state2flag, ftmod_ss7_ckt_flag2str, sng_ckt_flag_t, CKT_FLAGS_NAMES, 31) +FTDM_ENUM_NAMES(BLK_FLAGS_NAMES, BLK_FLAGS_STRING) +FTDM_STR2ENUM(ftmod_ss7_blk_state2flag, ftmod_ss7_blk_flag2str, sng_ckt_block_flag_t, BLK_FLAGS_NAMES, 31) + /* FUNCTIONS ******************************************************************/ uint8_t copy_cgPtyNum_from_sngss7(ftdm_caller_data_t *ftdm, SiCgPtyNum *cgPtyNum) { @@ -1484,6 +1487,11 @@ ftdm_status_t check_for_reconfig_flag(ftdm_span_t *ftdmspan) { ftdm_channel_t *ftdmchan = NULL; sngss7_chan_data_t *sngss7_info = NULL; + sng_isup_inf_t *sngss7_intf = NULL; + uint8_t state; + uint8_t bits_ab = 0; + uint8_t bits_cd = 0; + uint8_t bits_ef = 0; int x; int ret; @@ -1494,7 +1502,7 @@ ftdm_status_t check_for_reconfig_flag(ftdm_span_t *ftdmspan) /* if the call data is NULL move on */ if (ftdmchan->call_data == NULL) { - SS7_WARN_CHAN(ftdmchan, "Reconfiguring channel that has not call_data!%s\n", " "); + SS7_WARN_CHAN(ftdmchan, "Found ftdmchan with no sig module data!%s\n", " "); continue; } @@ -1503,12 +1511,136 @@ ftdm_status_t check_for_reconfig_flag(ftdm_span_t *ftdmspan) /* check the reconfig flag */ if (sngss7_test_ckt_flag(sngss7_info, FLAG_CKT_RECONFIG)) { - ret = ftmod_ss7_isup_ckt_config(sngss7_info->circuit->id); + /* confirm the state of all isup interfaces*/ + check_status_of_all_isup_intf(); - if (ret) { - SS7_CRITICAL("ISUP CKT %d re-configuration FAILED!\n", x); + sngss7_intf = &g_ftdm_sngss7_data.cfg.isupIntf[sngss7_info->circuit->infId]; + + /* check if the interface is paused or resumed */ + if (sngss7_test_flag(sngss7_intf, SNGSS7_PAUSED)) { + SS7_DEBUG_CHAN(ftdmchan, "ISUP intf %d is PAUSED\n", sngss7_intf->id); + /* throw the pause flag */ + sngss7_clear_ckt_flag(sngss7_info, FLAG_INFID_RESUME); + sngss7_set_ckt_flag(sngss7_info, FLAG_INFID_PAUSED); } else { - SS7_INFO("ISUP CKT %d re-configuration DONE!\n", x); + SS7_DEBUG_CHAN(ftdmchan, "ISUP intf %d is RESUMED\n", sngss7_intf->id); + /* throw the resume flag */ + sngss7_clear_ckt_flag(sngss7_info, FLAG_INFID_PAUSED); + sngss7_set_ckt_flag(sngss7_info, FLAG_INFID_RESUME); + } + + /* query for the status of the ckt */ + if (ftmod_ss7_isup_ckt_sta(sngss7_info->circuit->id, &state)) { + SS7_ERROR("Failed to read isup ckt = %d status\n", sngss7_info->circuit->id); + continue; + } + + /* extract the bit sections */ + bits_ab = (state & (SNG_BIT_A + SNG_BIT_B)) >> 0; + bits_cd = (state & (SNG_BIT_C + SNG_BIT_D)) >> 2; + bits_ef = (state & (SNG_BIT_E + SNG_BIT_F)) >> 4; + + if (bits_cd == 0x0) { + /* check if circuit is UCIC or transient */ + if (bits_ab == 0x3) { + /* bit a and bit b are set, unequipped */ + ret = ftmod_ss7_isup_ckt_config(sngss7_info->circuit->id); + if (ret) { + SS7_CRITICAL("ISUP CKT %d re-configuration FAILED!\n",x); + } else { + SS7_INFO("ISUP CKT %d re-configuration DONE!\n", x); + } + + /* reset the circuit to sync states */ + ftdm_mutex_lock(ftdmchan->mutex); + + /* flag the circuit as active */ + sngss7_set_flag(sngss7_info->circuit, SNGSS7_ACTIVE); + + /* throw the channel into reset */ + sngss7_set_ckt_flag(sngss7_info, FLAG_RESET_TX); + + /* throw the channel to suspend */ + ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_SUSPENDED); + + /* unlock the channel */ + ftdm_mutex_unlock(ftdmchan->mutex); + + } /* if (bits_ab == 0x3) */ + } else { + /* check the maintenance block status in bits A and B */ + switch (bits_ab) { + /**************************************************************************/ + case (0): + /* no maintenace block...do nothing */ + break; + /**************************************************************************/ + case (1): + /* locally blocked */ + sngss7_set_ckt_blk_flag(sngss7_info, FLAG_CKT_LC_BLOCK_RX); + + /* set the channel to suspended state */ + SS7_STATE_CHANGE(ftdmchan, FTDM_CHANNEL_STATE_SUSPENDED); + break; + /**************************************************************************/ + case (2): + /* remotely blocked */ + sngss7_set_ckt_blk_flag(sngss7_info, FLAG_CKT_MN_BLOCK_RX); + + /* set the channel to suspended state */ + SS7_STATE_CHANGE(ftdmchan, FTDM_CHANNEL_STATE_SUSPENDED); + break; + /**************************************************************************/ + case (3): + /* both locally and remotely blocked */ + sngss7_set_ckt_blk_flag(sngss7_info, FLAG_CKT_LC_BLOCK_RX); + sngss7_set_ckt_blk_flag(sngss7_info, FLAG_CKT_MN_BLOCK_RX); + + /* set the channel to suspended state */ + SS7_STATE_CHANGE(ftdmchan, FTDM_CHANNEL_STATE_SUSPENDED); + break; + /**************************************************************************/ + default: + break; + /**************************************************************************/ + } /* switch (bits_ab) */ + + /* check the hardware block status in bits e and f */ + switch (bits_ef) { + /**************************************************************************/ + case (0): + /* no maintenace block...do nothing */ + break; + /**************************************************************************/ + case (1): + /* locally blocked */ + sngss7_set_ckt_blk_flag(sngss7_info, FLAG_GRP_HW_BLOCK_TX); + + /* set the channel to suspended state */ + SS7_STATE_CHANGE(ftdmchan, FTDM_CHANNEL_STATE_SUSPENDED); + break; + /**************************************************************************/ + case (2): + /* remotely blocked */ + sngss7_set_ckt_blk_flag(sngss7_info, FLAG_GRP_HW_BLOCK_RX); + + /* set the channel to suspended state */ + SS7_STATE_CHANGE(ftdmchan, FTDM_CHANNEL_STATE_SUSPENDED); + break; + /**************************************************************************/ + case (3): + /* both locally and remotely blocked */ + sngss7_set_ckt_blk_flag(sngss7_info, FLAG_GRP_HW_BLOCK_TX); + sngss7_set_ckt_blk_flag(sngss7_info, FLAG_GRP_HW_BLOCK_RX); + + /* set the channel to suspended state */ + SS7_STATE_CHANGE(ftdmchan, FTDM_CHANNEL_STATE_SUSPENDED); + break; + /**************************************************************************/ + default: + break; + /**************************************************************************/ + } /* switch (bits_ef) */ } /* clear the re-config flag ... no matter what */