From abb8f08bbbf7d22a96f876a3ca7029fa1c63a93a Mon Sep 17 00:00:00 2001 From: Konrad Hammel Date: Thu, 23 Sep 2010 11:04:10 -0400 Subject: [PATCH 1/2] freetdm: ss7 - bug fixes --- .../ftmod_sangoma_ss7/ftmod_sangoma_ss7_cfg.c | 36 ++-- .../ftmod_sangoma_ss7/ftmod_sangoma_ss7_cli.c | 15 ++ .../ftmod_sangoma_ss7_cntrl.c | 6 +- .../ftmod_sangoma_ss7_handle.c | 144 ++++----------- .../ftmod_sangoma_ss7_main.c | 44 ++++- .../ftmod_sangoma_ss7_main.h | 18 +- .../ftmod_sangoma_ss7_support.c | 164 ++++++++++++++++++ 7 files changed, 290 insertions(+), 137 deletions(-) diff --git a/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_cfg.c b/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_cfg.c index 21ab1d32d2..21feb4f8fe 100644 --- a/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_cfg.c +++ b/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_cfg.c @@ -85,35 +85,35 @@ int ft_to_sngss7_cfg_all(void) if (ftmod_ss7_mtp1_gen_config()) { SS7_CRITICAL("MTP1 General configuration FAILED!\n"); - SS7_ASSERT + return 1; } else { SS7_INFO("MTP1 General configuration DONE\n"); } if (ftmod_ss7_mtp2_gen_config()) { SS7_CRITICAL("MTP2 General configuration FAILED!\n"); - SS7_ASSERT + return 1; } else { SS7_INFO("MTP2 General configuration DONE\n"); } if (ftmod_ss7_mtp3_gen_config()) { SS7_CRITICAL("MTP3 General configuration FAILED!\n"); - SS7_ASSERT + return 1; } else { SS7_INFO("MTP3 General configuration DONE\n"); } if (ftmod_ss7_isup_gen_config()) { SS7_CRITICAL("ISUP General configuration FAILED!\n"); - SS7_ASSERT + return 1; } else { SS7_INFO("ISUP General configuration DONE\n"); } if (ftmod_ss7_cc_gen_config()) { SS7_CRITICAL("CC General configuration FAILED!\n"); - SS7_ASSERT + return 1; } else { SS7_INFO("CC General configuration DONE\n"); } @@ -131,7 +131,7 @@ int ft_to_sngss7_cfg_all(void) /* configure mtp1 */ if (ftmod_ss7_mtp1_psap_config(x)) { SS7_CRITICAL("MTP1 PSAP %d configuration FAILED!\n", x); - SS7_ASSERT; + return 1;; } else { SS7_INFO("MTP1 PSAP %d configuration DONE!\n", x); } @@ -139,7 +139,7 @@ int ft_to_sngss7_cfg_all(void) /* configure mtp2 */ if (ftmod_ss7_mtp2_dlsap_config(x)) { SS7_CRITICAL("MTP2 DLSAP %d configuration FAILED!\n",x); - SS7_ASSERT; + return 1;; } else { SS7_INFO("MTP2 DLSAP %d configuration DONE!\n", x); } @@ -147,7 +147,7 @@ int ft_to_sngss7_cfg_all(void) /* configure mtp3 */ if (ftmod_ss7_mtp3_dlsap_config(x)) { SS7_CRITICAL("MTP3 DLSAP %d configuration FAILED!\n", x); - SS7_ASSERT; + return 1;; } else { SS7_INFO("MTP3 DLSAP %d configuration DONE!\n", x); } @@ -166,14 +166,14 @@ int ft_to_sngss7_cfg_all(void) if (ftmod_ss7_mtp3_nsap_config(x)) { SS7_CRITICAL("MTP3 NSAP %d configuration FAILED!\n", x); - SS7_ASSERT + return 1; } else { SS7_INFO("MTP3 NSAP %d configuration DONE!\n", x); } if (ftmod_ss7_isup_nsap_config(x)) { SS7_CRITICAL("ISUP NSAP %d configuration FAILED!\n", x); - SS7_ASSERT + return 1; } else { SS7_INFO("ISUP NSAP %d configuration DONE!\n", x); } @@ -192,7 +192,7 @@ int ft_to_sngss7_cfg_all(void) if (ftmod_ss7_mtp3_linkset_config(x)) { SS7_CRITICAL("MTP3 LINKSET %d configuration FAILED!\n", x); - SS7_ASSERT + return 1; } else { SS7_INFO("MTP3 LINKSET %d configuration DONE!\n", x); } @@ -211,7 +211,7 @@ int ft_to_sngss7_cfg_all(void) if (ftmod_ss7_mtp3_route_config(x)) { SS7_CRITICAL("MTP3 ROUTE %d configuration FAILED!\n", x); - SS7_ASSERT + return 1; } else { SS7_INFO("MTP3 ROUTE %d configuration DONE!\n",x); } @@ -227,7 +227,7 @@ int ft_to_sngss7_cfg_all(void) if (ftmod_ss7_mtp3_route_config(0)) { SS7_CRITICAL("MTP3 ROUTE 0 configuration FAILED!\n"); - SS7_ASSERT + return 1; } else { SS7_INFO("MTP3 ROUTE 0 configuration DONE!\n"); } @@ -244,14 +244,14 @@ int ft_to_sngss7_cfg_all(void) if (ftmod_ss7_isup_isap_config(x)) { SS7_CRITICAL("ISUP ISAP %d configuration FAILED!\n", x); - SS7_ASSERT + return 1; } else { SS7_INFO("ISUP ISAP %d configuration DONE!\n", x); } if (ftmod_ss7_cc_isap_config(x)) { SS7_CRITICAL("CC ISAP %d configuration FAILED!\n", x); - SS7_ASSERT + return 1; } else { SS7_INFO("CC ISAP %d configuration DONE!\n", x); } @@ -270,9 +270,11 @@ int ft_to_sngss7_cfg_all(void) if (ftmod_ss7_isup_intf_config(x)) { SS7_CRITICAL("ISUP INTF %d configuration FAILED!\n", x); - SS7_ASSERT + return 1; } else { SS7_INFO("ISUP INTF %d configuration DONE!\n", x); + /* set the interface to paused */ + sngss7_set_flag(&g_ftdm_sngss7_data.cfg.isupIntf[x], SNGSS7_PAUSED); } /* set the CONFIGURED flag */ @@ -289,7 +291,7 @@ int ft_to_sngss7_cfg_all(void) if ( g_ftdm_sngss7_data.cfg.isupCkt[x].type == 0) { if (ftmod_ss7_isup_ckt_config(x)) { SS7_CRITICAL("ISUP CKT %d configuration FAILED!\n", x); - SS7_ASSERT + return 1; } else { SS7_INFO("ISUP CKT %d configuration DONE!\n", x); } 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 cf56f51a0a..6ccc693478 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 @@ -1156,7 +1156,12 @@ static ftdm_status_t handle_tx_blo(ftdm_stream_handle_t *stream, int span, int c /* 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", ss7_info->circuit->cic); + /* check if we need to die */ SS7_ASSERT; + /* unlock the channel again before we exit */ + ftdm_mutex_unlock(ftdmchan->mutex); + /* move to the next channel */ + continue; } else { /* throw the ckt block flag */ sngss7_set_flag(ss7_info, FLAG_CKT_MN_BLOCK_TX); @@ -1217,7 +1222,12 @@ static ftdm_status_t handle_tx_ubl(ftdm_stream_handle_t *stream, int span, int c /* 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", ss7_info->circuit->cic); + /* check if we need to die */ SS7_ASSERT; + /* unlock the channel again before we exit */ + ftdm_mutex_unlock(ftdmchan->mutex); + /* move to the next channel */ + continue; } else { /* throw the ckt block flag */ sngss7_set_flag(ss7_info, FLAG_CKT_MN_UNBLK_TX); @@ -1466,7 +1476,12 @@ static ftdm_status_t handle_tx_grs(ftdm_stream_handle_t *stream, int span, int c /* 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); + /* check if we need to die */ SS7_ASSERT; + /* unlock the channel again before we exit */ + ftdm_mutex_unlock(ftdmchan->mutex); + /* move to the next channel */ + continue; } else { /* throw the grp reset flag */ sngss7_set_flag(sngss7_info, FLAG_GRP_RESET_TX); 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 0d76329d25..87733dd594 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 @@ -75,7 +75,7 @@ int ft_to_sngss7_activate_all(void) if (ftmod_ss7_enable_isap(x)) { SS7_CRITICAL("ISAP %d Enable: NOT OK\n", x); - SS7_ASSERT; + return 1; } else { SS7_INFO("ISAP %d Enable: OK\n", x); } @@ -94,7 +94,7 @@ int ft_to_sngss7_activate_all(void) if (ftmod_ss7_enable_nsap(x)) { SS7_CRITICAL("NSAP %d Enable: NOT OK\n", x); - SS7_ASSERT; + return 1; } else { SS7_INFO("NSAP %d Enable: OK\n", x); } @@ -113,7 +113,7 @@ int ft_to_sngss7_activate_all(void) if (ftmod_ss7_enable_mtpLinkSet(x)) { SS7_CRITICAL("LinkSet \"%s\" Enable: NOT OK\n", g_ftdm_sngss7_data.cfg.mtpLinkSet[x].name); - SS7_ASSERT; + return 1; } else { SS7_INFO("LinkSet \"%s\" Enable: OK\n", g_ftdm_sngss7_data.cfg.mtpLinkSet[x].name); } 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 5e6a246ba2..ac7a61646f 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 @@ -1029,6 +1029,9 @@ ftdm_status_t handle_pause(uint32_t suInstId, uint32_t spInstId, uint32_t circui /* extract the affected infId from the circuit structure */ infId = g_ftdm_sngss7_data.cfg.isupCkt[circuit].infId; + + /* set the interface to paused */ + sngss7_set_flag(&g_ftdm_sngss7_data.cfg.isupIntf[infId], SNGSS7_PAUSED); /* go through all the circuits now and find any other circuits on this infId */ i = 1; @@ -1050,6 +1053,7 @@ ftdm_status_t handle_pause(uint32_t suInstId, uint32_t spInstId, uint32_t circui /* check if the circuit is fully started */ if (ftdm_test_flag(ftdmchan->span, FTDM_SPAN_IN_THREAD)) { + SS7_DEBUG_CHAN(ftdmchan, "Rx PAUSE%s\n", ""); /* set the pause flag on the channel */ sngss7_set_flag(sngss7_info, FLAG_INFID_PAUSED); } @@ -1081,6 +1085,9 @@ ftdm_status_t handle_resume(uint32_t suInstId, uint32_t spInstId, uint32_t circu /* extract the affect infId from the circuit structure */ infId = g_ftdm_sngss7_data.cfg.isupCkt[circuit].infId; + /* set the interface to resumed */ + sngss7_clear_flag(&g_ftdm_sngss7_data.cfg.isupIntf[infId], SNGSS7_PAUSED); + /* go through all the circuits now and find any other circuits on this infId */ i = 1; while (g_ftdm_sngss7_data.cfg.isupCkt[i].id != 0) { @@ -1101,6 +1108,8 @@ ftdm_status_t handle_resume(uint32_t suInstId, uint32_t spInstId, uint32_t circu /* only resume if we are paused */ if (sngss7_test_flag(sngss7_info, FLAG_INFID_PAUSED)) { + SS7_DEBUG_CHAN(ftdmchan, "Rx RESUME%s\n", ""); + /* set the resume flag on the channel */ sngss7_set_flag(sngss7_info, FLAG_INFID_RESUME); @@ -1527,7 +1536,7 @@ ftdm_status_t handle_grs_req(uint32_t suInstId, uint32_t spInstId, uint32_t circ ftdm_channel_t *ftdmchan = NULL; sngss7_span_data_t *sngss7_span = NULL; int range; - int x; + if (extract_chan_data(circuit, &sngss7_info, &ftdmchan)) { SS7_ERROR("Failed to extract channel data for circuit = %d!\n", circuit); @@ -1544,51 +1553,12 @@ ftdm_status_t handle_grs_req(uint32_t suInstId, uint32_t spInstId, uint32_t circ return FTDM_FAIL; } - /* loop over the cics starting from circuit until range+1 */ - for (x = circuit; x < (circuit + range + 1); x++) { - if (g_ftdm_sngss7_data.cfg.isupCkt[x].type != VOICE) continue; - /* grab the circuit in question */ - if (extract_chan_data(x, &sngss7_info, &ftdmchan)) { - SS7_ERROR("Failed to extract channel data for circuit = %d!\n", x); - break; - } - - /* lock the channel */ - ftdm_mutex_lock(ftdmchan->mutex); + /* fill in the span structure for this circuit */ + sngss7_span = ftdmchan->span->mod_data; + sngss7_span->rx_grs.circuit = circuit; + sngss7_span->rx_grs.range = range; - /* fill in the span structure for this circuit */ - sngss7_span = ftdmchan->span->mod_data; - sngss7_span->rx_grs.circuit = circuit; - sngss7_span->rx_grs.range = range; - - SS7_INFO_CHAN(ftdmchan, "Rx GRS (%d:%d)\n", - g_ftdm_sngss7_data.cfg.isupCkt[circuit].cic, - (g_ftdm_sngss7_data.cfg.isupCkt[circuit].cic + range)); - - /* flag the channel as having received a reset */ - sngss7_set_flag(sngss7_info, FLAG_GRP_RESET_RX); - - switch (ftdmchan->state) { - /**************************************************************************/ - case FTDM_CHANNEL_STATE_RESTART: - - /* go to idle so that we can redo the restart state*/ - ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_IDLE); - - break; - /**************************************************************************/ - default: - - /* set the state of the channel to restart...the rest is done by the chan monitor */ - ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_RESTART); - break; - /**************************************************************************/ - } - - /* unlock the channel again before we exit */ - ftdm_mutex_unlock(ftdmchan->mutex); - - } + /* the reset will be started in the main thread by "check_if_rx_grs_started" */ SS7_FUNC_TRACE_EXIT(__FUNCTION__); return FTDM_SUCCESS; @@ -1599,10 +1569,16 @@ ftdm_status_t handle_grs_rsp(uint32_t suInstId, uint32_t spInstId, uint32_t circ { SS7_FUNC_TRACE_ENTER(__FUNCTION__); - sngss7_chan_data_t *sngss7_info = NULL; - ftdm_channel_t *ftdmchan = NULL; + sngss7_chan_data_t *sngss7_info = NULL; + ftdm_channel_t *ftdmchan = NULL; + sngss7_span_data_t *sngss7_span = NULL; int range; - int x; + + if (extract_chan_data(circuit, &sngss7_info, &ftdmchan)) { + SS7_ERROR("Failed to extract channel data for circuit = %d!\n", circuit); + SS7_FUNC_TRACE_EXIT(__FUNCTION__); + return FTDM_FAIL; + } /* extract the range value from the event structure */ if ((siStaEvnt->rangStat.eh.pres == PRSNT_NODEF) && (siStaEvnt->rangStat.range.pres == PRSNT_NODEF)) { @@ -1613,70 +1589,20 @@ ftdm_status_t handle_grs_rsp(uint32_t suInstId, uint32_t spInstId, uint32_t circ return FTDM_FAIL; } - /* go through all the circuits in the range */ - for ( x = circuit; x < (circuit + range + 1); x++) { + /* fill in the span structure for this circuit */ + sngss7_span = ftdmchan->span->mod_data; + sngss7_span->rx_gra.circuit = circuit; + sngss7_span->rx_gra.range = range; - /* grab the circuit in question */ - if (extract_chan_data(x, &sngss7_info, &ftdmchan)) { - SS7_ERROR("Failed to extract channel data for circuit = %d!\n", circuit); - break; - } + /* check if there is a cause value in the GRA */ + if ((siStaEvnt != NULL) && + (siStaEvnt->causeDgn.eh.pres == PRSNT_NODEF) && + (siStaEvnt->causeDgn.causeVal.pres == PRSNT_NODEF)) { - /* lock the channel */ - ftdm_mutex_lock(ftdmchan->mutex); - - SS7_INFO_CHAN(ftdmchan, "Rx GRA (%d:%d)\n", - g_ftdm_sngss7_data.cfg.isupCkt[circuit].cic, - (g_ftdm_sngss7_data.cfg.isupCkt[circuit].cic + range)); + sngss7_span->rx_gra.cause = siStaEvnt->causeDgn.causeVal.val; + } - switch (ftdmchan->state) { - /**********************************************************************/ - case FTDM_CHANNEL_STATE_RESTART: - - /* throw the FLAG_RESET_TX_RSP to indicate we have acknowledgement from the remote side */ - sngss7_set_flag(sngss7_info, FLAG_GRP_RESET_TX_RSP); - - /* go to DOWN */ - ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_DOWN); - - break; - /**********************************************************************/ - case FTDM_CHANNEL_STATE_DOWN: - - /* do nothing, just drop the message */ - SS7_DEBUG("Receveived GRA in down state, dropping\n"); - - break; - /**********************************************************************/ - case FTDM_CHANNEL_STATE_TERMINATING: - case FTDM_CHANNEL_STATE_HANGUP: - case FTDM_CHANNEL_STATE_HANGUP_COMPLETE: - - /* throw the FLAG_RESET_TX_RSP to indicate we have acknowledgement from the remote side */ - sngss7_set_flag(sngss7_info, FLAG_GRP_RESET_TX_RSP); - - break; - /**********************************************************************/ - default: - /* ITU Q764-2.9.5.1.c -> release the circuit */ - if ((siStaEvnt != NULL) && - (siStaEvnt->causeDgn.eh.pres ==PRSNT_NODEF) && - (siStaEvnt->causeDgn.causeVal.pres == PRSNT_NODEF)) { - ftdmchan->caller_data.hangup_cause = siStaEvnt->causeDgn.causeVal.val; - } else { - ftdmchan->caller_data.hangup_cause = 98; /* Message not compatiable with call state */ - } - - /* go to terminating to hang up the call */ - ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_TERMINATING); - break; - /**********************************************************************/ - } - - /* unlock the channel again before we exit */ - ftdm_mutex_unlock(ftdmchan->mutex); - - } /* for (( x = 0; x < (circuit + range); x++) */ + /* the reset will be started in the main thread by "check_if_rx_gra_started" */ SS7_FUNC_TRACE_EXIT(__FUNCTION__); return FTDM_SUCCESS; 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 3ef8db53d1..ce9423cd00 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 @@ -46,7 +46,7 @@ ftdm_sngss7_data_t g_ftdm_sngss7_data; /* PROTOTYPES *****************************************************************/ static void *ftdm_sangoma_ss7_run (ftdm_thread_t * me, void *obj); -static void ftdm_sangoma_ss7_process_state_change (ftdm_channel_t *ftdmchan); +void ftdm_sangoma_ss7_process_state_change (ftdm_channel_t *ftdmchan); static void ftdm_sangoma_ss7_process_stack_event (sngss7_event_data_t *sngss7_event); static ftdm_status_t ftdm_sangoma_ss7_stop (ftdm_span_t * span); @@ -342,8 +342,16 @@ static void *ftdm_sangoma_ss7_run(ftdm_thread_t * me, void *obj) /**********************************************************************/ } /* switch ((ftdm_interrupt_wait(ftdm_sangoma_ss7_int, 100))) */ + /* check if there is a GRA to proccess on the span */ + if (sngss7_span->rx_gra.range > 0) { + check_if_rx_gra_started(ftdmspan); + } /* if (sngss7->span->rx_gra.range > 0) */ + /* check if there is a GRS being processed on the span */ if (sngss7_span->rx_grs.range > 0) { + /* check if the rx_grs has started */ + check_if_rx_grs_started(ftdmspan); + /* check if the rx_grs has cleared */ check_if_rx_grs_processed(ftdmspan); } /* if (sngss7_span->rx_grs.range > 0) */ @@ -452,7 +460,7 @@ static void ftdm_sangoma_ss7_process_stack_event (sngss7_event_data_t *sngss7_ev } /******************************************************************************/ -static void ftdm_sangoma_ss7_process_state_change (ftdm_channel_t * ftdmchan) +void ftdm_sangoma_ss7_process_state_change (ftdm_channel_t * ftdmchan) { sngss7_chan_data_t *sngss7_info = ftdmchan->call_data; int i = 0; @@ -727,6 +735,11 @@ static void ftdm_sangoma_ss7_process_state_change (ftdm_channel_t * ftdmchan) /**************************************************************************/ case FTDM_CHANNEL_STATE_DOWN: /*the call is finished and removed */ + if (ftdmchan->last_state == FTDM_CHANNEL_STATE_SUSPENDED) { + SS7_DEBUG("re-entering state from processing block/unblock request ... do nothing\n"); + break; + } + /* check if there is a reset response that needs to be sent */ if (sngss7_test_flag (sngss7_info, FLAG_RESET_RX)) { /* send a RSC-RLC */ @@ -776,6 +789,11 @@ static void ftdm_sangoma_ss7_process_state_change (ftdm_channel_t * ftdmchan) sngss7_clear_flag(sngss7_info, FLAG_GRP_RESET_TX); sngss7_clear_flag(sngss7_info, FLAG_GRP_RESET_BASE); sngss7_clear_flag(sngss7_info, FLAG_GRP_RESET_SENT); + + /* clean out the spans GRA structure */ + sngss7_span_data_t *span = ftdmchan->span->mod_data; + span->rx_gra.circuit = 0; + span->rx_gra.range = 0; } /* check if we came from reset (aka we just processed a reset) */ @@ -965,6 +983,7 @@ static void ftdm_sangoma_ss7_process_state_change (ftdm_channel_t * ftdmchan) /**********************************************************************/ if (sngss7_test_flag(sngss7_info, FLAG_INFID_RESUME)) { + SS7_DEBUG_CHAN(ftdmchan, "Processing RESUME%s\n", ""); /* clear the RESUME flag */ sngss7_clear_flag(sngss7_info, FLAG_INFID_RESUME); @@ -990,6 +1009,7 @@ static void ftdm_sangoma_ss7_process_state_change (ftdm_channel_t * ftdmchan) } /* if (sngss7_test_flag(sngss7_info, FLAG_INFID_RESUME)) */ if (sngss7_test_flag(sngss7_info, FLAG_INFID_PAUSED)) { + SS7_DEBUG_CHAN(ftdmchan, "Processing PAUSE%s\n", ""); /* bring the sig status down */ sigev.event_id = FTDM_SIGEVENT_SIGSTATUS_CHANGED; @@ -1165,9 +1185,10 @@ static FIO_CHANNEL_OUTGOING_CALL_FUNCTION(ftdm_sangoma_ss7_outgoing_call) /* 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); - SS7_FUNC_TRACE_EXIT(__FUNCTION__); + /* check if we need to die */ SS7_ASSERT; + /* end the request */ + goto outgoing_fail; }; /* check if the channel sig state is UP */ @@ -1278,6 +1299,7 @@ static ftdm_status_t ftdm_sangoma_ss7_start(ftdm_span_t * span) ftdm_channel_t *ftdmchan = NULL; sngss7_chan_data_t *sngss7_info = NULL; sngss7_span_data_t *sngss7_span = NULL; + sng_isup_inf_t *sngss7_intf = NULL; int x; @@ -1290,12 +1312,22 @@ static ftdm_status_t ftdm_sangoma_ss7_start(ftdm_span_t * span) if (ftdmchan->call_data == NULL) continue; sngss7_info = ftdmchan->call_data; sngss7_span = ftdmchan->span->mod_data; + sngss7_intf = &g_ftdm_sngss7_data.cfg.isupIntf[sngss7_info->circuit->infId]; + /* lock the channel */ ftdm_mutex_lock(ftdmchan->mutex); - /* throw the pause flag */ - sngss7_set_flag(sngss7_info, FLAG_INFID_PAUSED); + /* check if the interface is paused or resumed */ + if (sngss7_test_flag(sngss7_intf, SNGSS7_PAUSED)) { + /* throw the pause flag */ + sngss7_clear_flag(sngss7_info, FLAG_INFID_RESUME); + sngss7_set_flag(sngss7_info, FLAG_INFID_PAUSED); + } else { + /* throw the pause flag */ + sngss7_clear_flag(sngss7_info, FLAG_INFID_PAUSED); + sngss7_set_flag(sngss7_info, FLAG_INFID_RESUME); + } #if 0 /* throw the grp reset flag */ sngss7_set_flag(sngss7_info, FLAG_GRP_RESET_TX); 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 850bbf0d1a..ae2412381c 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 @@ -79,7 +79,8 @@ typedef enum { typedef enum { CONFIGURED = (1 << 0), - ACTIVE = (1 << 1) + ACTIVE = (1 << 1), + SNGSS7_PAUSED = (1 << 7) } sng_flag_t; typedef struct sng_mtp_link { @@ -335,6 +336,7 @@ typedef struct sngss7_group_data { uint32_t range; uint8_t status[255]; uint8_t type; + uint8_t cause; }sngss7_group_data_t; typedef struct sngss7_chan_data { @@ -353,6 +355,7 @@ typedef struct sngss7_chan_data { typedef struct sngss7_span_data { ftdm_sched_t *sched; sngss7_group_data_t rx_grs; + sngss7_group_data_t rx_gra; sngss7_group_data_t tx_grs; sngss7_group_data_t rx_cgb; sngss7_group_data_t tx_cgb; @@ -427,6 +430,8 @@ extern int cmbLinkSetId; /******************************************************************************/ /* PROTOTYPES *****************************************************************/ +void ftdm_sangoma_ss7_process_state_change (ftdm_channel_t *ftdmchan); + void handle_sng_log(uint8_t level, char *fmt,...); void handle_sng_mtp1_alarm(Pst *pst, L1Mngmt *sta); void handle_sng_mtp2_alarm(Pst *pst, SdMngmt *sta); @@ -546,7 +551,9 @@ void handle_isup_t35(void *userdata); ftdm_status_t ftdm_sngss7_handle_cli_cmd(ftdm_stream_handle_t *stream, const char *data); +ftdm_status_t check_if_rx_grs_started(ftdm_span_t *ftdmspan); ftdm_status_t check_if_rx_grs_processed(ftdm_span_t *ftdmspan); +ftdm_status_t check_if_rx_gra_started(ftdm_span_t *ftdmspan); ftdm_status_t check_for_res_sus_flag(ftdm_span_t *ftdmspan); /******************************************************************************/ @@ -678,7 +685,14 @@ ftdm_status_t check_for_res_sus_flag(ftdm_span_t *ftdmspan); #define sngss7_clear_flag(obj, flag) ((obj)->flags &= ~(flag)) #define sngss7_set_flag(obj, flag) ((obj)->flags |= (flag)) -# define SS7_ASSERT *(int*)0=0; +#ifdef SS7_PRODUCTION +# define SS7_ASSERT \ + SS7_INFO_CHAN(ftdmchan,"Production Mode, continuing%s\n", ""); +#else +# define SS7_ASSERT \ + SS7_ERROR_CHAN(ftdmchan, "Debugging Mode, ending%s\n", ""); \ + *(int*)0=0; +#endif /******************************************************************************/ /******************************************************************************/ 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 aaffeb0a36..8e7c6496aa 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 @@ -57,7 +57,9 @@ unsigned long get_unique_id(void); ftdm_status_t extract_chan_data(uint32_t circuit, sngss7_chan_data_t **sngss7_info, ftdm_channel_t **ftdmchan); +ftdm_status_t check_if_rx_grs_started(ftdm_span_t *ftdmspan); ftdm_status_t check_if_rx_grs_processed(ftdm_span_t *ftdmspan); +ftdm_status_t check_if_rx_gra_started(ftdm_span_t *ftdmspan); ftdm_status_t check_for_res_sus_flag(ftdm_span_t *ftdmspan); /******************************************************************************/ @@ -445,6 +447,68 @@ unsigned long get_unique_id(void) return(sngss7_id); } +/******************************************************************************/ +ftdm_status_t check_if_rx_grs_started(ftdm_span_t *ftdmspan) +{ + ftdm_channel_t *ftdmchan = NULL; + sngss7_chan_data_t *sngss7_info = NULL; + sngss7_span_data_t *sngss7_span = (sngss7_span_data_t *)ftdmspan->mod_data; + int i; + + for ( i = sngss7_span->rx_grs.circuit; i < (sngss7_span->rx_grs.circuit + sngss7_span->rx_grs.range + 1); i++) { + + /* extract the channel in question */ + if (extract_chan_data(i, &sngss7_info, &ftdmchan)) { + SS7_ERROR("Failed to extract channel data for circuit = %d!\n", i); + continue; + } + + /* check if the GRP_RESET_RX flag is already up */ + if (sngss7_test_flag(sngss7_info, FLAG_GRP_RESET_RX)) { + /* we have already processed this channel...move along */ + continue; + } + + /* lock the channel */ + ftdm_mutex_lock(ftdmchan->mutex); + + /* clear up any pending state changes */ + while (ftdm_test_flag (ftdmchan, FTDM_CHANNEL_STATE_CHANGE)) { + ftdm_sangoma_ss7_process_state_change (ftdmchan); + } + + SS7_INFO_CHAN(ftdmchan, "Rx GRS (%d:%d)\n", + g_ftdm_sngss7_data.cfg.isupCkt[sngss7_span->rx_grs.circuit].cic, + (g_ftdm_sngss7_data.cfg.isupCkt[sngss7_span->rx_grs.circuit].cic + sngss7_span->rx_grs.range)); + + /* flag the channel as having received a reset */ + sngss7_set_flag(sngss7_info, FLAG_GRP_RESET_RX); + + switch (ftdmchan->state) { + /**************************************************************************/ + case FTDM_CHANNEL_STATE_RESTART: + + /* go to idle so that we can redo the restart state*/ + ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_IDLE); + + break; + /**************************************************************************/ + default: + + /* set the state of the channel to restart...the rest is done by the chan monitor */ + ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_RESTART); + break; + /**************************************************************************/ + } /* switch (ftdmchan->state) */ + + /* unlock the channel again before we exit */ + ftdm_mutex_unlock(ftdmchan->mutex); + + } /* for (chans in GRS */ + + return FTDM_SUCCESS; +} + /******************************************************************************/ ftdm_status_t check_if_rx_grs_processed(ftdm_span_t *ftdmspan) { @@ -493,7 +557,10 @@ ftdm_status_t check_if_rx_grs_processed(ftdm_span_t *ftdmspan) /* extract the channel in question */ if (extract_chan_data(i, &sngss7_info, &ftdmchan)) { SS7_ERROR("Failed to extract channel data for circuit = %d!\n",i); + /* check if we need to die */ SS7_ASSERT; + /* move along */ + continue; } /* throw the GRP reset flag complete flag */ @@ -534,6 +601,91 @@ GRS_UNLOCK_ALL: return FTDM_SUCCESS; } +/******************************************************************************/ +ftdm_status_t check_if_rx_gra_started(ftdm_span_t *ftdmspan) +{ + ftdm_channel_t *ftdmchan = NULL; + sngss7_chan_data_t *sngss7_info = NULL; + sngss7_span_data_t *sngss7_span = (sngss7_span_data_t *)ftdmspan->mod_data; + int i; + + for ( i = sngss7_span->rx_gra.circuit; i < (sngss7_span->rx_gra.circuit + sngss7_span->rx_gra.range + 1); i++) { + + /* extract the channel in question */ + if (extract_chan_data(i, &sngss7_info, &ftdmchan)) { + SS7_ERROR("Failed to extract channel data for circuit = %d!\n", i); + continue; + } + + /* check if the channel is already procoessing the GRA */ + if (sngss7_test_flag(sngss7_info, FLAG_GRP_RESET_TX_RSP)) { + /* move along */ + continue; + } + + /* lock the channel */ + ftdm_mutex_lock(ftdmchan->mutex); + + /* clear up any pending state changes */ + while (ftdm_test_flag (ftdmchan, FTDM_CHANNEL_STATE_CHANGE)) { + ftdm_sangoma_ss7_process_state_change (ftdmchan); + } + + SS7_INFO_CHAN(ftdmchan, "Rx GRA (%d:%d)\n", + g_ftdm_sngss7_data.cfg.isupCkt[sngss7_span->rx_gra.circuit].cic, + (g_ftdm_sngss7_data.cfg.isupCkt[sngss7_span->rx_gra.circuit].cic + sngss7_span->rx_gra.range)); + + switch (ftdmchan->state) { + /**********************************************************************/ + case FTDM_CHANNEL_STATE_RESTART: + + /* throw the FLAG_RESET_TX_RSP to indicate we have acknowledgement from the remote side */ + sngss7_set_flag(sngss7_info, FLAG_GRP_RESET_TX_RSP); + + /* go to DOWN */ + ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_DOWN); + + break; + /**********************************************************************/ + case FTDM_CHANNEL_STATE_DOWN: + + /* do nothing, just drop the message */ + SS7_DEBUG("Receveived GRA in down state, dropping\n"); + + break; + /**********************************************************************/ + case FTDM_CHANNEL_STATE_TERMINATING: + case FTDM_CHANNEL_STATE_HANGUP: + case FTDM_CHANNEL_STATE_HANGUP_COMPLETE: + + /* throw the FLAG_RESET_TX_RSP to indicate we have acknowledgement from the remote side */ + sngss7_set_flag(sngss7_info, FLAG_GRP_RESET_TX_RSP); + + break; + /**********************************************************************/ + default: + /* ITU Q764-2.9.5.1.c -> release the circuit */ + if (sngss7_span->rx_gra.cause != 0) { + ftdmchan->caller_data.hangup_cause = sngss7_span->rx_gra.cause; + } else { + ftdmchan->caller_data.hangup_cause = 98; /* Message not compatiable with call state */ + } + + /* go to terminating to hang up the call */ + ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_TERMINATING); + break; + /**********************************************************************/ + } + + /* unlock the channel again before we exit */ + ftdm_mutex_unlock(ftdmchan->mutex); + + } /* for ( circuits in request */ + + + return FTDM_SUCCESS; +} + /******************************************************************************/ ftdm_status_t check_for_res_sus_flag(ftdm_span_t *ftdmspan) { @@ -564,6 +716,11 @@ ftdm_status_t check_for_res_sus_flag(ftdm_span_t *ftdmspan) /* if we have the PAUSED flag and the sig status is still UP */ if ((sngss7_test_flag(sngss7_info, FLAG_INFID_PAUSED)) && (ftdm_test_flag(ftdmchan, FTDM_CHANNEL_SIG_UP))) { + + /* clear up any pending state changes */ + while (ftdm_test_flag (ftdmchan, FTDM_CHANNEL_STATE_CHANGE)) { + ftdm_sangoma_ss7_process_state_change (ftdmchan); + } /* throw the channel into SUSPENDED to process the flag */ /* after doing this once the sig status will be down */ @@ -573,6 +730,13 @@ ftdm_status_t check_for_res_sus_flag(ftdm_span_t *ftdmspan) /* if the RESUME flag is up go to SUSPENDED to process the flag */ /* after doing this the flag will be cleared */ if (sngss7_test_flag(sngss7_info, FLAG_INFID_RESUME)) { + + /* clear up any pending state changes */ + while (ftdm_test_flag (ftdmchan, FTDM_CHANNEL_STATE_CHANGE)) { + ftdm_sangoma_ss7_process_state_change (ftdmchan); + } + + /* got SUSPENDED state to clear the flag */ ftdm_set_state_locked (ftdmchan, FTDM_CHANNEL_STATE_SUSPENDED); } From dd529b0e3abcd72cea921068377f2abfd7b28d5e Mon Sep 17 00:00:00 2001 From: Moises Silva Date: Fri, 24 Sep 2010 17:34:40 -0400 Subject: [PATCH 2/2] freetdm: remove ftdm_cpu_monitor_disable API (dup) --- libs/freetdm/sample/boost/ftdmstart.c | 7 ------- libs/freetdm/sample/dso/ftdmload.c | 2 -- libs/freetdm/sample/sched/ftdmsched.c | 2 -- libs/freetdm/src/include/freetdm.h | 10 ---------- 4 files changed, 21 deletions(-) diff --git a/libs/freetdm/sample/boost/ftdmstart.c b/libs/freetdm/sample/boost/ftdmstart.c index 972ed43146..bff0664bce 100644 --- a/libs/freetdm/sample/boost/ftdmstart.c +++ b/libs/freetdm/sample/boost/ftdmstart.c @@ -313,13 +313,6 @@ int main(int argc, char *argv[]) /* set the logging level to use */ ftdm_global_set_default_logger(FTDM_LOG_LEVEL_DEBUG); - /* this is optional. - * cpu monitor is a default feature in freetdm that launches 1 thread - * to monitor system-wide CPU usage. If it goes above a predefined threshold - * it will stop accepting calls to try to protect the quality of current calls */ - ftdm_cpu_monitor_disable(); - - /* Initialize the FTDM library */ if (ftdm_global_init() != FTDM_SUCCESS) { fprintf(stderr, "Error loading FreeTDM\n"); diff --git a/libs/freetdm/sample/dso/ftdmload.c b/libs/freetdm/sample/dso/ftdmload.c index 5b150d67ed..80bcc02fc0 100644 --- a/libs/freetdm/sample/dso/ftdmload.c +++ b/libs/freetdm/sample/dso/ftdmload.c @@ -134,8 +134,6 @@ int main(int argc, char *argv[]) ftdm_global_set_default_logger(FTDM_LOG_LEVEL_DEBUG); - ftdm_cpu_monitor_disable(); - if (ftdm_global_init() != FTDM_SUCCESS) { fprintf(stderr, "Error loading FreeTDM\n"); exit(-1); diff --git a/libs/freetdm/sample/sched/ftdmsched.c b/libs/freetdm/sample/sched/ftdmsched.c index 5cd7d6340a..e6e391ee4b 100644 --- a/libs/freetdm/sample/sched/ftdmsched.c +++ b/libs/freetdm/sample/sched/ftdmsched.c @@ -73,8 +73,6 @@ int main(int argc, char *argv[]) ftdm_global_set_default_logger(FTDM_LOG_LEVEL_DEBUG); - ftdm_cpu_monitor_disable(); - if (ftdm_global_init() != FTDM_SUCCESS) { fprintf(stderr, "Error loading FreeTDM\n"); exit(-1); diff --git a/libs/freetdm/src/include/freetdm.h b/libs/freetdm/src/include/freetdm.h index 078875b09c..a418152251 100644 --- a/libs/freetdm/src/include/freetdm.h +++ b/libs/freetdm/src/include/freetdm.h @@ -1176,16 +1176,6 @@ FT_DECLARE(ftdm_iterator_t *) ftdm_span_get_chan_iterator(const ftdm_span_t *spa */ FT_DECLARE(char *) ftdm_api_execute(const char *cmd); -/*! - * \brief Disables CPU monitoring - * - * \note CPU monitoring is enabled by default. This means a thread will be launched at startup (ftdm_global_init) - * with the sole purpose of monitoring system-wide CPU usage. If the CPU usage raises above a defined - * threshold, no new calls will be accepted (neither incoming or outgoing) - * - */ -FT_DECLARE(void) ftdm_cpu_monitor_disable(void); - /*! * \brief Create a configuration node *