From 95cf2209fe50c127e88d0021ac93b36c73a407c5 Mon Sep 17 00:00:00 2001 From: Moises Silva Date: Mon, 20 Sep 2010 10:18:23 -0400 Subject: [PATCH 01/15] freetdm: make conf nodes to be stored in FIFO order --- libs/freetdm/src/ftdm_config.c | 25 +++++++++++++------ libs/freetdm/src/include/private/ftdm_types.h | 6 +++++ 2 files changed, 24 insertions(+), 7 deletions(-) diff --git a/libs/freetdm/src/ftdm_config.c b/libs/freetdm/src/ftdm_config.c index 4ba2e19c67..f6d9c1ae30 100644 --- a/libs/freetdm/src/ftdm_config.c +++ b/libs/freetdm/src/ftdm_config.c @@ -268,13 +268,24 @@ FT_DECLARE(ftdm_status_t) ftdm_conf_node_create(const char *name, ftdm_conf_node if (parent) { /* store who my parent is */ newnode->parent = parent; - /* save any siblings */ - sibling = parent->child; - /* as a newborn I am first */ - parent->child = newnode; - if (sibling) { - /* store a pointer to my next sibling */ - newnode->next = sibling; + + /* arrange them in FIFO order (newnode should be last) */ + if (!parent->child) { + /* we're the first node being added */ + parent->child = newnode; + } else { + if (!parent->last) { + /* we're the second node being added */ + parent->last = newnode; + parent->child->next = newnode; + newnode->prev = parent->child; + } else { + /* we're the third or Nth node to be added */ + sibling = parent->last; + sibling->next = newnode; + parent->last = newnode; + newnode->prev = sibling; + } } } diff --git a/libs/freetdm/src/include/private/ftdm_types.h b/libs/freetdm/src/include/private/ftdm_types.h index ba6956344d..d0d19e5a55 100644 --- a/libs/freetdm/src/include/private/ftdm_types.h +++ b/libs/freetdm/src/include/private/ftdm_types.h @@ -322,9 +322,15 @@ struct ftdm_conf_node { /* first node child */ struct ftdm_conf_node *child; + /* last node child */ + struct ftdm_conf_node *last; + /* next node sibling */ struct ftdm_conf_node *next; + /* prev node sibling */ + struct ftdm_conf_node *prev; + /* my parent if any */ struct ftdm_conf_node *parent; }; From 108ae5c48a0f74f0f5c2725aa95145867426a7c8 Mon Sep 17 00:00:00 2001 From: Konrad Hammel Date: Mon, 20 Sep 2010 16:48:36 -0400 Subject: [PATCH 02/15] freetdm: ss7 - numerous updates --- .../ftmod_sangoma_ss7/ftmod_sangoma_ss7_cli.c | 24 + .../ftmod_sangoma_ss7_handle.c | 459 ++++++------------ .../ftmod_sangoma_ss7_logger.c | 8 + .../ftmod_sangoma_ss7_main.c | 55 ++- .../ftmod_sangoma_ss7/ftmod_sangoma_ss7_out.c | 45 +- .../ftmod_sangoma_ss7_support.c | 92 ++-- 6 files changed, 291 insertions(+), 392 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 20e1f27c9b..cf56f51a0a 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 @@ -1506,6 +1506,10 @@ static ftdm_status_t handle_tx_cgb(ftdm_stream_handle_t *stream, int span, int c sngss7_span_data_t *sngss7_span; int byte = 0; int bit = 0; + ftdm_sigmsg_t sigev; + + memset (&sigev, 0, sizeof (sigev)); + if (range > 31) { stream->write_function(stream, "Invalid range value %d", range); @@ -1531,6 +1535,14 @@ static ftdm_status_t handle_tx_cgb(ftdm_stream_handle_t *stream, int span, int c /* throw the grp maint. block flag */ sngss7_set_flag(sngss7_info, FLAG_GRP_MN_BLOCK_TX); + /* bring the sig status down */ + sigev.chan_id = ftdmchan->chan_id; + sigev.span_id = ftdmchan->span_id; + sigev.channel = ftdmchan; + sigev.event_id = FTDM_SIGEVENT_SIGSTATUS_CHANGED; + sigev.sigstatus = FTDM_SIG_STATE_DOWN; + ftdm_span_send_signal(ftdmchan->span, &sigev); + /* if this is the first channel in the range */ if (ftdmchan->physical_chan_id == chan) { /* attach the cgb information */ @@ -1575,6 +1587,10 @@ static ftdm_status_t handle_tx_cgu(ftdm_stream_handle_t *stream, int span, int c sngss7_span_data_t *sngss7_span; int byte = 0; int bit = 0; + ftdm_sigmsg_t sigev; + + memset (&sigev, 0, sizeof (sigev)); + if (range > 31) { stream->write_function(stream, "Invalid range value %d", range); @@ -1600,6 +1616,14 @@ static ftdm_status_t handle_tx_cgu(ftdm_stream_handle_t *stream, int span, int c /* throw the grp maint. block flag */ sngss7_clear_flag(sngss7_info, FLAG_GRP_MN_BLOCK_TX); + /* bring the sig status up */ + sigev.chan_id = ftdmchan->chan_id; + sigev.span_id = ftdmchan->span_id; + sigev.channel = ftdmchan; + sigev.event_id = FTDM_SIGEVENT_SIGSTATUS_CHANGED; + sigev.sigstatus = FTDM_SIG_STATE_UP; + ftdm_span_send_signal(ftdmchan->span, &sigev); + /* if this is the first channel in the range */ if (ftdmchan->physical_chan_id == chan) { /* attach the cgb information */ 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 263b599ddc..5e6a246ba2 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 @@ -93,21 +93,13 @@ ftdm_status_t handle_con_ind(uint32_t suInstId, uint32_t spInstId, uint32_t circ return FTDM_FAIL; } - /* now that we have the right channel...put a lock on it so no-one else can use it */ + /* lock the channel */ 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); - SS7_FUNC_TRACE_EXIT(__FUNCTION__); - SS7_ASSERT; - }; - if (sngss7_test_flag(sngss7_info, FLAG_GLARE)) { - SS7_MSG_TRACE(ftdmchan, sngss7_info, "Rx IAM (glare detected on circuit)\n"); + SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Rx IAM (glare)\n", sngss7_info->circuit->cic); } else { - SS7_MSG_TRACE(ftdmchan, sngss7_info, "Rx IAM\n"); + SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Rx IAM\n", sngss7_info->circuit->cic); } /* check if the circuit has a remote block */ @@ -287,21 +279,13 @@ ftdm_status_t handle_con_sta(uint32_t suInstId, uint32_t spInstId, uint32_t circ return FTDM_FAIL; } - /* now that we have the right channel...put a lock on it so no-one else can use it */ + /* lock the channel */ 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); - SS7_FUNC_TRACE_EXIT(__FUNCTION__); - SS7_ASSERT; - } - switch (evntType) { /**************************************************************************/ case (ADDRCMPLT): - SS7_MSG_TRACE(ftdmchan, sngss7_info, "Rx ACM\n"); + SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Rx ACM\n", sngss7_info->circuit->cic); switch (ftdmchan->state) { /**********************************************************************/ case FTDM_CHANNEL_STATE_DIALING: @@ -322,115 +306,115 @@ ftdm_status_t handle_con_sta(uint32_t suInstId, uint32_t spInstId, uint32_t circ } /* switch (ftdmchan->state) */ /**************************************************************************/ case (MODIFY): - SS7_MSG_TRACE(ftdmchan, sngss7_info, "Rx MODIFY\n"); + SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Rx MODIFY\n", sngss7_info->circuit->cic); break; /**************************************************************************/ case (MODCMPLT): - SS7_MSG_TRACE(ftdmchan, sngss7_info, "Rx MODIFY-COMPLETE\n"); + SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Rx MODIFY-COMPLETE\n", sngss7_info->circuit->cic); break; /**************************************************************************/ case (MODREJ): - SS7_MSG_TRACE(ftdmchan, sngss7_info, "Rx MODIFY-REJECT\n"); + SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Rx MODIFY-REJECT\n", sngss7_info->circuit->cic); break; /**************************************************************************/ case (PROGRESS): - SS7_MSG_TRACE(ftdmchan, sngss7_info, "Rx CPG\n"); + SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Rx CPG\n", sngss7_info->circuit->cic); break; /**************************************************************************/ case (FRWDTRSFR): - SS7_MSG_TRACE(ftdmchan, sngss7_info, "Rx FOT\n"); + SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Rx FOT\n", sngss7_info->circuit->cic); break; /**************************************************************************/ case (INFORMATION): - SS7_MSG_TRACE(ftdmchan, sngss7_info, "Rx INF\n"); + SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Rx INF\n", sngss7_info->circuit->cic); break; /**************************************************************************/ case (INFORMATREQ): - SS7_MSG_TRACE(ftdmchan, sngss7_info, "Rx INR\n"); + SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Rx INR\n", sngss7_info->circuit->cic); break; /**************************************************************************/ case (SUBSADDR): - SS7_MSG_TRACE(ftdmchan, sngss7_info, "Rx SAM\n"); + SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Rx SAM\n", sngss7_info->circuit->cic); break; /**************************************************************************/ case (EXIT): - SS7_MSG_TRACE(ftdmchan, sngss7_info, "Rx EXIT\n"); + SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Rx EXIT\n", sngss7_info->circuit->cic); break; /**************************************************************************/ case (NETRESMGT): - SS7_MSG_TRACE(ftdmchan, sngss7_info, "Rx NRM\n"); + SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Rx NRM\n", sngss7_info->circuit->cic); break; /**************************************************************************/ case (IDENTREQ): - SS7_MSG_TRACE(ftdmchan, sngss7_info, "Rx IDR\n"); + SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Rx IDR\n", sngss7_info->circuit->cic); break; /**************************************************************************/ case (IDENTRSP): - SS7_MSG_TRACE(ftdmchan, sngss7_info, "Rx IRS\n"); + SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Rx IRS\n", sngss7_info->circuit->cic); break; /**************************************************************************/ case (MALCLLPRNT): - SS7_MSG_TRACE(ftdmchan, sngss7_info, "Rx MALICIOUS CALL\n"); + SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Rx MALICIOUS CALL\n", sngss7_info->circuit->cic); break; /**************************************************************************/ case (CHARGE): - SS7_MSG_TRACE(ftdmchan, sngss7_info, "Rx CRG\n"); + SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Rx CRG\n", sngss7_info->circuit->cic); break; /**************************************************************************/ case (TRFFCHGE): - SS7_MSG_TRACE(ftdmchan, sngss7_info, "Rx CRG-TARIFF\n"); + SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Rx CRG-TARIFF\n", sngss7_info->circuit->cic); break; /**************************************************************************/ case (CHARGEACK): - SS7_MSG_TRACE(ftdmchan, sngss7_info, "Rx CRG-ACK\n"); + SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Rx CRG-ACK\n", sngss7_info->circuit->cic); break; /**************************************************************************/ case (CALLOFFMSG): - SS7_MSG_TRACE(ftdmchan, sngss7_info, "Rx CALL-OFFER\n"); + SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Rx CALL-OFFER\n", sngss7_info->circuit->cic); break; /**************************************************************************/ case (LOOPPRVNT): - SS7_MSG_TRACE(ftdmchan, sngss7_info, "Rx LOP\n"); + SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Rx LOP\n", sngss7_info->circuit->cic); break; /**************************************************************************/ case (TECT_TIMEOUT): - SS7_MSG_TRACE(ftdmchan, sngss7_info, "Rx ECT-Timeout\n"); + SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Rx ECT-Timeout\n", sngss7_info->circuit->cic); break; /**************************************************************************/ case (RINGSEND): - SS7_MSG_TRACE(ftdmchan, sngss7_info, "Rx RINGING-SEND\n"); + SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Rx RINGING-SEND\n", sngss7_info->circuit->cic); break; /**************************************************************************/ case (CALLCLEAR): - SS7_MSG_TRACE(ftdmchan, sngss7_info, "Rx CALL-LINE Clear\n"); + SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Rx CALL-LINE Clear\n", sngss7_info->circuit->cic); break; /**************************************************************************/ case (PRERELEASE): - SS7_MSG_TRACE(ftdmchan, sngss7_info, "Rx PRI\n"); + SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Rx PRI\n", sngss7_info->circuit->cic); break; /**************************************************************************/ case (APPTRANSPORT): - SS7_MSG_TRACE(ftdmchan, sngss7_info, "Rx APM\n"); + SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Rx APM\n", sngss7_info->circuit->cic); break; /**************************************************************************/ case (OPERATOR): - SS7_MSG_TRACE(ftdmchan, sngss7_info, "Rx OPERATOR\n"); + SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Rx OPERATOR\n", sngss7_info->circuit->cic); break; /**************************************************************************/ case (METPULSE): - SS7_MSG_TRACE(ftdmchan, sngss7_info, "Rx METERING-PULSE\n"); + SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Rx METERING-PULSE\n", sngss7_info->circuit->cic); break; /**************************************************************************/ case (CLGPTCLR): - SS7_MSG_TRACE(ftdmchan, sngss7_info, "Rx CALLING_PARTY_CLEAR\n"); + SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Rx CALLING_PARTY_CLEAR\n", sngss7_info->circuit->cic); break; /**************************************************************************/ case (SUBDIRNUM): - SS7_MSG_TRACE(ftdmchan, sngss7_info, "Rx SUB-DIR\n"); + SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Rx SUB-DIR\n", sngss7_info->circuit->cic); break; /**************************************************************************/ default: - SS7_MSG_TRACE(ftdmchan, sngss7_info, "Rx Unknown Msg\n"); + SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Rx Unknown Msg\n", sngss7_info->circuit->cic); break; /**************************************************************************/ } @@ -457,25 +441,16 @@ ftdm_status_t handle_con_cfm(uint32_t suInstId, uint32_t spInstId, uint32_t circ return FTDM_FAIL; } - /* now that we have the right channel...put a lock on it so no-one else can use it */ + /* lock the channel */ 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); - SS7_FUNC_TRACE_EXIT(__FUNCTION__); - SS7_ASSERT; - }; - - /* check whether the ftdm channel is in a state to accept a call */ switch (ftdmchan->state) { /**************************************************************************/ case FTDM_CHANNEL_STATE_PROGRESS: case FTDM_CHANNEL_STATE_PROGRESS_MEDIA: - SS7_MSG_TRACE(ftdmchan, sngss7_info, "Rx ANM\n"); + SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Rx ANM\n", sngss7_info->circuit->cic); /* go to UP */ ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_UP); @@ -484,7 +459,7 @@ ftdm_status_t handle_con_cfm(uint32_t suInstId, uint32_t spInstId, uint32_t circ /**************************************************************************/ case FTDM_CHANNEL_STATE_DIALING: - SS7_MSG_TRACE(ftdmchan, sngss7_info, "Rx CON\n"); + SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Rx CON\n", sngss7_info->circuit->cic); /* go to UP */ ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_UP); @@ -493,7 +468,7 @@ ftdm_status_t handle_con_cfm(uint32_t suInstId, uint32_t spInstId, uint32_t circ /**************************************************************************/ default: /* incorrect state...reset the CIC */ - SS7_MSG_TRACE(ftdmchan, sngss7_info, "Rx ANM/CON\n"); + SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Rx ANM/CON\n", sngss7_info->circuit->cic); /* throw the TX reset flag */ sngss7_set_flag(sngss7_info, FLAG_GRP_RESET_TX); @@ -527,18 +502,12 @@ ftdm_status_t handle_rel_ind(uint32_t suInstId, uint32_t spInstId, uint32_t circ return FTDM_FAIL; } - /* now that we have the right channel...put a lock on it so no-one else can use it */ + /* lock the channel */ 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); - SS7_FUNC_TRACE_EXIT(__FUNCTION__); - SS7_ASSERT; - }; - - SS7_MSG_TRACE(ftdmchan, sngss7_info, "Rx REL\n"); + SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Rx REL cause=%d\n", + sngss7_info->circuit->cic, + siRelEvnt->causeDgn.causeVal.val); /* check whether the ftdm channel is in a state to release a call */ switch (ftdmchan->state) { @@ -616,18 +585,10 @@ ftdm_status_t handle_rel_cfm(uint32_t suInstId, uint32_t spInstId, uint32_t circ return FTDM_FAIL; } - /* now that we have the right channel...put a lock on it so no-one else can use it */ + /* lock the channel */ 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); - SS7_FUNC_TRACE_EXIT(__FUNCTION__); - SS7_ASSERT; - }; - - SS7_MSG_TRACE(ftdmchan, sngss7_info, "Rx RLC\n"); + SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Rx RLC\n", sngss7_info->circuit->cic); /* check whether the ftdm channel is in a state to accept a call */ switch (ftdmchan->state) { @@ -675,18 +636,10 @@ ftdm_status_t handle_dat_ind(uint32_t suInstId, uint32_t spInstId, uint32_t circ return FTDM_FAIL; } - /* now that we have the right channel...put a lock on it so no-one else can use it */ + /* lock the channel */ 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); - SS7_FUNC_TRACE_EXIT(__FUNCTION__); - SS7_ASSERT; - }; - - SS7_MSG_TRACE(ftdmchan, sngss7_info, "Rx DATA IND\n"); + SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Rx DATA IND\n", sngss7_info->circuit->cic); /* unlock the channel */ ftdm_mutex_unlock(ftdmchan->mutex); @@ -710,18 +663,10 @@ ftdm_status_t handle_fac_ind(uint32_t suInstId, uint32_t spInstId, uint32_t circ return FTDM_FAIL; } - /* now that we have the right channel...put a lock on it so no-one else can use it */ + /* lock the channel */ 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); - SS7_FUNC_TRACE_EXIT(__FUNCTION__); - SS7_ASSERT; - }; - - SS7_MSG_TRACE(ftdmchan, sngss7_info, "Rx FAC\n"); + SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Rx FAC\n", sngss7_info->circuit->cic); /* unlock the channel */ ftdm_mutex_unlock(ftdmchan->mutex); @@ -745,18 +690,10 @@ ftdm_status_t handle_fac_cfm(uint32_t suInstId, uint32_t spInstId, uint32_t circ return FTDM_FAIL; } - /* now that we have the right channel...put a lock on it so no-one else can use it */ + /* lock the channel */ 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); - SS7_FUNC_TRACE_EXIT(__FUNCTION__); - SS7_ASSERT; - }; - - SS7_MSG_TRACE(ftdmchan, sngss7_info, "Rx FAC-CON\n"); + SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Rx FAC-CON\n", sngss7_info->circuit->cic); /* unlock the channel */ ftdm_mutex_unlock(ftdmchan->mutex); @@ -780,18 +717,10 @@ ftdm_status_t handle_umsg_ind(uint32_t suInstId, uint32_t spInstId, uint32_t cir return FTDM_FAIL; } - /* now that we have the right channel...put a lock on it so no-one else can use it */ + /* lock the channel */ 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); - SS7_FUNC_TRACE_EXIT(__FUNCTION__); - SS7_ASSERT; - }; - - SS7_MSG_TRACE(ftdmchan, sngss7_info, "Rx USER-USER msg\n"); + SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Rx USER-USER msg\n", sngss7_info->circuit->cic); /* unlock the channel */ ftdm_mutex_unlock(ftdmchan->mutex); @@ -818,217 +747,217 @@ ftdm_status_t handle_sta_ind(uint32_t suInstId, uint32_t spInstId, uint32_t circ switch (evntType) { /**************************************************************************/ case SIT_STA_REATTEMPT: /* reattempt indication */ - SS7_MSG_TRACE(ftdmchan, sngss7_info, "Rx Reattempt indication\n"); + SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Rx Reattempt indication\n", sngss7_info->circuit->cic); handle_reattempt(suInstId, spInstId, circuit, globalFlg, evntType, siStaEvnt); break; /**************************************************************************/ case SIT_STA_ERRORIND: /* error indication */ - SS7_MSG_TRACE(ftdmchan, sngss7_info, "Rx Error indication\n"); + SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Rx Error indication\n", sngss7_info->circuit->cic); SS7_WARN(" %s indication not currently supported\n", DECODE_LCC_EVENT(evntType)); break; /**************************************************************************/ case SIT_STA_CONTCHK: /* continuity check */ - SS7_MSG_TRACE(ftdmchan, sngss7_info, "Rx COT start\n"); + SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Rx COT start\n", sngss7_info->circuit->cic); handle_cot_start(suInstId, spInstId, circuit, globalFlg, evntType, siStaEvnt); break; /**************************************************************************/ case SIT_STA_CONTREP: /* continuity report */ - SS7_MSG_TRACE(ftdmchan, sngss7_info, "Rx COT report\n"); + SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Rx COT report\n", sngss7_info->circuit->cic); handle_cot(suInstId, spInstId, circuit, globalFlg, evntType, siStaEvnt); break; /**************************************************************************/ case SIT_STA_STPCONTIN: /* stop continuity */ - SS7_MSG_TRACE(ftdmchan, sngss7_info, "Rx COT stop\n"); + SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Rx COT stop\n", sngss7_info->circuit->cic); handle_cot_stop(suInstId, spInstId, circuit, globalFlg, evntType, siStaEvnt); break; /**************************************************************************/ case SIT_STA_CGQRYRSP: /* circuit grp query response from far end forwarded to upper layer by ISUP */ - SS7_MSG_TRACE(ftdmchan, sngss7_info, "Rx CQM\n"); + SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Rx CQM\n", sngss7_info->circuit->cic); SS7_WARN(" %s indication not currently supported\n", DECODE_LCC_EVENT(evntType)); break; /**************************************************************************/ case SIT_STA_CONFUSION: /* confusion */ - SS7_MSG_TRACE(ftdmchan, sngss7_info, "Rx CFN\n"); + SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Rx CFN\n", sngss7_info->circuit->cic); SS7_WARN(" %s indication not currently supported\n", DECODE_LCC_EVENT(evntType)); break; /**************************************************************************/ case SIT_STA_LOOPBACKACK: /* loop-back acknowledge */ - SS7_MSG_TRACE(ftdmchan, sngss7_info, "Rx LPA\n"); + SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Rx LPA\n", sngss7_info->circuit->cic); SS7_WARN(" %s indication not currently supported\n", DECODE_LCC_EVENT(evntType)); break; /**************************************************************************/ case SIT_STA_CIRRSRVREQ: /* circuit reservation request */ - SS7_MSG_TRACE(ftdmchan, sngss7_info, "Rx Ckt Resveration req\n"); + SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Rx Ckt Resveration req\n", sngss7_info->circuit->cic); SS7_WARN(" %s indication not currently supported\n", DECODE_LCC_EVENT(evntType)); break; /**************************************************************************/ case SIT_STA_CIRRSRVACK: /* circuit reservation acknowledgement */ - SS7_MSG_TRACE(ftdmchan, sngss7_info, "Rx Ckt Res ack\n"); + SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Rx Ckt Res ack\n", sngss7_info->circuit->cic); SS7_WARN(" %s indication not currently supported\n", DECODE_LCC_EVENT(evntType)); break; /**************************************************************************/ case SIT_STA_CIRBLOREQ: /* circuit blocking request */ - SS7_MSG_TRACE(ftdmchan, sngss7_info, "Rx BLO\n"); + SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Rx BLO\n", sngss7_info->circuit->cic); handle_blo_req(suInstId, spInstId, circuit, globalFlg, evntType, siStaEvnt); break; /**************************************************************************/ case SIT_STA_CIRBLORSP: /* circuit blocking response */ - SS7_MSG_TRACE(ftdmchan, sngss7_info, "Rx BLA\n"); + SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Rx BLA\n", sngss7_info->circuit->cic); handle_blo_rsp(suInstId, spInstId, circuit, globalFlg, evntType, siStaEvnt); break; /**************************************************************************/ case SIT_STA_CIRUBLREQ: /* circuit unblocking request */ - SS7_MSG_TRACE(ftdmchan, sngss7_info, "Rx UBL\n"); + SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Rx UBL\n", sngss7_info->circuit->cic); handle_ubl_req(suInstId, spInstId, circuit, globalFlg, evntType, siStaEvnt); break; /**************************************************************************/ case SIT_STA_CIRUBLRSP: /* circuit unblocking response */ - SS7_MSG_TRACE(ftdmchan, sngss7_info, "Rx UBA\n"); + SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Rx UBA\n", sngss7_info->circuit->cic); handle_ubl_rsp(suInstId, spInstId, circuit, globalFlg, evntType, siStaEvnt); break; /**************************************************************************/ case SIT_STA_CIRRESREQ: /* circuit reset request - RSC */ - SS7_MSG_TRACE(ftdmchan, sngss7_info, "Rx RSC\n"); + SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Rx RSC\n", sngss7_info->circuit->cic); handle_rsc_req(suInstId, spInstId, circuit, globalFlg, evntType, siStaEvnt); break; /**************************************************************************/ case SIT_STA_CIRLOCRES: /* reset initiated locally by the software */ - SS7_MSG_TRACE(ftdmchan, sngss7_info, "Rx Local RSC\n"); + SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Rx Local RSC\n", sngss7_info->circuit->cic); handle_local_rsc_req(suInstId, spInstId, circuit, globalFlg, evntType, siStaEvnt); break; /**************************************************************************/ case SIT_STA_CIRRESRSP: /* circuit reset response */ - SS7_MSG_TRACE(ftdmchan, sngss7_info, "Rx RSC-RLC\n"); + SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Rx RSC-RLC\n", sngss7_info->circuit->cic); handle_rsc_rsp(suInstId, spInstId, circuit, globalFlg, evntType, siStaEvnt); break; /**************************************************************************/ case SIT_STA_CGBREQ: /* CGB request */ - SS7_MSG_TRACE(ftdmchan, sngss7_info, "Rx CGB\n"); + SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Rx CGB\n", sngss7_info->circuit->cic); handle_cgb_req(suInstId, spInstId, circuit, globalFlg, evntType, siStaEvnt); break; /**************************************************************************/ case SIT_STA_CGUREQ: /* CGU request */ - SS7_MSG_TRACE(ftdmchan, sngss7_info, "Rx CGU\n"); + SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Rx CGU\n", sngss7_info->circuit->cic); handle_cgu_req(suInstId, spInstId, circuit, globalFlg, evntType, siStaEvnt); break; /**************************************************************************/ case SIT_STA_CGQRYREQ: /* circuit group query request */ - SS7_MSG_TRACE(ftdmchan, sngss7_info, "Rx CQM\n"); + SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Rx CQM\n", sngss7_info->circuit->cic); SS7_WARN(" %s indication not currently supported\n", DECODE_LCC_EVENT(evntType)); break; /**************************************************************************/ case SIT_STA_CGBRSP: /* mntc. oriented CGB response */ - SS7_MSG_TRACE(ftdmchan, sngss7_info, "Rx mntc CGB\n"); + SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Rx mntc CGB\n", sngss7_info->circuit->cic); /*handle_cgb_req(suInstId, spInstId, circuit, globalFlg, evntType, siStaEvnt);*/ break; /**************************************************************************/ case SIT_STA_CGURSP: /* mntc. oriented CGU response */ - SS7_MSG_TRACE(ftdmchan, sngss7_info, "Rx mntc CGU\n"); + SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Rx mntc CGU\n", sngss7_info->circuit->cic); /*SS7_WARN(" %s indication not currently supported\n", DECODE_LCC_EVENT(evntType));*/ break; /**************************************************************************/ case SIT_STA_GRSREQ: /* circuit group reset request */ - SS7_MSG_TRACE(ftdmchan, sngss7_info, "Rx GRS\n"); + SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Rx GRS\n", sngss7_info->circuit->cic); handle_grs_req(suInstId, spInstId, circuit, globalFlg, evntType, siStaEvnt); break; /**************************************************************************/ case SIT_STA_CIRUNEQPD: /* circuit unequipped indication */ - SS7_MSG_TRACE(ftdmchan, sngss7_info, "Rx UCIC\n"); + SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Rx UCIC\n", sngss7_info->circuit->cic); handle_ucic(suInstId, spInstId, circuit, globalFlg, evntType, siStaEvnt); break; /**************************************************************************/ case SIT_STA_GRSRSP: /* circuit group reset response */ - SS7_MSG_TRACE(ftdmchan, sngss7_info, "Rx GRA\n"); + SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Rx GRA\n", sngss7_info->circuit->cic); handle_grs_rsp(suInstId, spInstId, circuit, globalFlg, evntType, siStaEvnt); break; /**************************************************************************/ case SIT_STA_PAUSEIND: /* pause indication */ - SS7_MSG_TRACE(ftdmchan, sngss7_info, "Rx SUS\n"); + SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Rx SUS\n", sngss7_info->circuit->cic); handle_pause(suInstId, spInstId, circuit, globalFlg, evntType, siStaEvnt); break; /**************************************************************************/ case SIT_STA_RESUMEIND: /* resume indication */ - SS7_MSG_TRACE(ftdmchan, sngss7_info, "Rx RES\n"); + SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Rx RES\n", sngss7_info->circuit->cic); handle_resume(suInstId, spInstId, circuit, globalFlg, evntType, siStaEvnt); break; /**************************************************************************/ case SIT_STA_USRPARTA: /* user part available */ - SS7_MSG_TRACE(ftdmchan, sngss7_info, "Rx UPA\n"); + SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Rx UPA\n", sngss7_info->circuit->cic); SS7_WARN(" %s indication not currently supported\n", DECODE_LCC_EVENT(evntType)); break; /**************************************************************************/ case SIT_STA_RMTUSRUNAV: /* remote user not available */ - SS7_MSG_TRACE(ftdmchan, sngss7_info, "Rx Remote User not Available\n"); + SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Rx Remote User not Available\n", sngss7_info->circuit->cic); SS7_WARN(" %s indication not currently supported\n", DECODE_LCC_EVENT(evntType)); break; /**************************************************************************/ case SIT_STA_MTPCONG0: /* congestion indication level 0 */ - SS7_MSG_TRACE(ftdmchan, sngss7_info, "Rx Congestion L0\n"); + SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Rx Congestion L0\n", sngss7_info->circuit->cic); SS7_WARN(" %s indication not currently supported\n", DECODE_LCC_EVENT(evntType)); break; /**************************************************************************/ case SIT_STA_MTPCONG1: /* congestion indication level 1 */ - SS7_MSG_TRACE(ftdmchan, sngss7_info, "Rx Congestion L1\n"); + SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Rx Congestion L1\n", sngss7_info->circuit->cic); SS7_WARN(" %s indication not currently supported\n", DECODE_LCC_EVENT(evntType)); break; /**************************************************************************/ case SIT_STA_MTPCONG2: /* congestion indication level 2 */ - SS7_MSG_TRACE(ftdmchan, sngss7_info, "Rx Congestion L2\n"); + SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Rx Congestion L2\n", sngss7_info->circuit->cic); SS7_WARN(" %s indication not currently supported\n", DECODE_LCC_EVENT(evntType)); break; /**************************************************************************/ case SIT_STA_MTPCONG3: /* congestion indication level 3 */ - SS7_MSG_TRACE(ftdmchan, sngss7_info, "Rx Congestion L3\n"); + SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Rx Congestion L3\n", sngss7_info->circuit->cic); SS7_WARN(" %s indication not currently supported\n", DECODE_LCC_EVENT(evntType)); break; /**************************************************************************/ case SIT_STA_MTPSTPCONG: /* stop congestion indication level 0 */ - SS7_MSG_TRACE(ftdmchan, sngss7_info, "Rx Stop Congestion\n"); + SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Rx Stop Congestion\n", sngss7_info->circuit->cic); SS7_WARN(" %s indication not currently supported\n", DECODE_LCC_EVENT(evntType)); break; /**************************************************************************/ case SIT_STA_CIRLOCALBLOIND: /* Mngmt local blocking */ - SS7_MSG_TRACE(ftdmchan, sngss7_info, "Rx Local BLO\n"); + SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Rx Local BLO\n", sngss7_info->circuit->cic); handle_local_blk(suInstId, spInstId, circuit, globalFlg, evntType, siStaEvnt); break; /**************************************************************************/ case SIT_STA_CIRLOCALUBLIND: /* Mngmt local unblocking */ - SS7_MSG_TRACE(ftdmchan, sngss7_info, "Rx Local UBL\n"); + SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Rx Local UBL\n", sngss7_info->circuit->cic); handle_local_ubl(suInstId, spInstId, circuit, globalFlg, evntType, siStaEvnt); break; /**************************************************************************/ case SIT_STA_OVERLOAD: /* Overload */ - SS7_MSG_TRACE(ftdmchan, sngss7_info, "Rx Overload\n"); + SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Rx Overload\n", sngss7_info->circuit->cic); SS7_WARN(" %s indication not currently supported\n", DECODE_LCC_EVENT(evntType)); break; /**************************************************************************/ case SIT_STA_LMCGBREQ: /* when LM requests ckt grp blocking */ - SS7_MSG_TRACE(ftdmchan, sngss7_info, "Rx LM CGB\n"); + SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Rx LM CGB\n", sngss7_info->circuit->cic); SS7_WARN(" %s indication not currently supported\n", DECODE_LCC_EVENT(evntType)); break; /**************************************************************************/ case SIT_STA_LMCGUREQ: /* when LM requests ckt grp unblocking */ - SS7_MSG_TRACE(ftdmchan, sngss7_info, "Rx LM CGU\n"); + SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Rx LM CGU\n", sngss7_info->circuit->cic); SS7_WARN(" %s indication not currently supported\n", DECODE_LCC_EVENT(evntType)); break; /**************************************************************************/ case SIT_STA_LMGRSREQ: /* when LM requests ckt grp reset */ - SS7_MSG_TRACE(ftdmchan, sngss7_info, "Rx LM RSC\n"); + SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Rx LM RSC\n", sngss7_info->circuit->cic); SS7_WARN(" %s indication not currently supported\n", DECODE_LCC_EVENT(evntType)); break; /**************************************************************************/ case SIT_STA_CGBINFOIND: /* circuit grp blking ind , no resp req */ - /*SS7_MSG_TRACE(ftdmchan, sngss7_info, "Rx CGB no resp req\n");*/ + /*SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Rx CGB no resp req\n", sngss7_info->circuit->cic);*/ /* handle_cgb_req(suInstId, spInstId, circuit, globalFlg, evntType, siStaEvnt);*/ break; /**************************************************************************/ case SIT_STA_LMCQMINFOREQ: /* when LM requests ckt grp query */ - SS7_MSG_TRACE(ftdmchan, sngss7_info, "Rx LM CQM\n"); + SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Rx LM CQM\n", sngss7_info->circuit->cic); // SS7_WARN(" %s indication not currently supported\n", DECODE_LCC_EVENT(evntType)); break; /**************************************************************************/ case SIT_STA_CIRLOCGRS: /* group reset initiated locally by the software */ - SS7_MSG_TRACE(ftdmchan, sngss7_info, "Rx Local GRS\n"); + SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Rx Local GRS\n", sngss7_info->circuit->cic); SS7_WARN(" %s indication not currently supported\n", DECODE_LCC_EVENT(evntType)); break; /**************************************************************************/ @@ -1057,17 +986,9 @@ ftdm_status_t handle_reattempt(uint32_t suInstId, uint32_t spInstId, uint32_t ci return FTDM_FAIL; } - /* now that we have the right channel...put a lock on it so no-one else can use it */ + /* lock the channel */ 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); - SS7_FUNC_TRACE_EXIT(__FUNCTION__); - SS7_ASSERT; - }; - if (sngss7_test_flag(sngss7_info, FLAG_GLARE)) { /* the glare flag is already up so it was caught ... do nothing */ SS7_DEBUG_CHAN(ftdmchan, "Glare flag is already up...nothing to do!%s\n", " "); @@ -1106,7 +1027,7 @@ ftdm_status_t handle_pause(uint32_t suInstId, uint32_t spInstId, uint32_t circui int infId; int i; - /* extract the affect infId from the circuit structure */ + /* extract the affected infId from the circuit structure */ infId = g_ftdm_sngss7_data.cfg.isupCkt[circuit].infId; /* go through all the circuits now and find any other circuits on this infId */ @@ -1216,17 +1137,9 @@ ftdm_status_t handle_cot_start(uint32_t suInstId, uint32_t spInstId, uint32_t ci return FTDM_FAIL; } - /* now that we have the right channel...put a lock on it so no-one else can use it */ + /* lock the channel */ 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); - SS7_FUNC_TRACE_EXIT(__FUNCTION__); - SS7_ASSERT; - }; - /* open the channel if it is not open */ if (!ftdm_test_flag(ftdmchan, FTDM_CHANNEL_OPEN)) { if (ftdm_channel_open_chan(ftdmchan) != FTDM_SUCCESS) { @@ -1274,17 +1187,9 @@ ftdm_status_t handle_cot_stop(uint32_t suInstId, uint32_t spInstId, uint32_t cir return FTDM_FAIL; } - /* now that we have the right channel...put a lock on it so no-one else can use it */ + /* lock the channel */ 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); - SS7_FUNC_TRACE_EXIT(__FUNCTION__); - SS7_ASSERT; - }; - /* tell the core to stop looping the channel */ ftdm_channel_command(ftdmchan, FTDM_COMMAND_DISABLE_LOOP, NULL); @@ -1335,17 +1240,9 @@ ftdm_status_t handle_blo_req(uint32_t suInstId, uint32_t spInstId, uint32_t circ return FTDM_FAIL; } - /* now that we have the right channel...put a lock on it so no-one else can use it */ + /* lock the channel */ 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); - SS7_FUNC_TRACE_EXIT(__FUNCTION__); - SS7_ASSERT; - }; - /* check if the circuit is already blocked or not */ if (sngss7_test_flag(sngss7_info, FLAG_CKT_MN_BLOCK_RX)) { SS7_WARN("Received BLO on circuit that is already blocked!\n"); @@ -1379,17 +1276,9 @@ ftdm_status_t handle_blo_rsp(uint32_t suInstId, uint32_t spInstId, uint32_t circ return FTDM_FAIL; } - /* now that we have the right channel...put a lock on it so no-one else can use it */ + /* lock the channel */ 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); - SS7_FUNC_TRACE_EXIT(__FUNCTION__); - SS7_ASSERT; - }; - /* KONRAD FIX ME */ /* unlock the channel again before we exit */ @@ -1414,17 +1303,9 @@ ftdm_status_t handle_ubl_req(uint32_t suInstId, uint32_t spInstId, uint32_t circ return FTDM_FAIL; } - /* now that we have the right channel...put a lock on it so no-one else can use it */ + /* lock the channel */ 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); - SS7_FUNC_TRACE_EXIT(__FUNCTION__); - SS7_ASSERT; - }; - /* check if the channel is blocked */ if (!(sngss7_test_flag(sngss7_info, FLAG_CKT_MN_BLOCK_RX))) { SS7_WARN("Received UBL on circuit that is not blocked!\n"); @@ -1461,17 +1342,9 @@ ftdm_status_t handle_ubl_rsp(uint32_t suInstId, uint32_t spInstId, uint32_t circ return FTDM_FAIL; } - /* now that we have the right channel...put a lock on it so no-one else can use it */ + /* lock the channel */ 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); - SS7_FUNC_TRACE_EXIT(__FUNCTION__); - SS7_ASSERT; - }; - /* KONRAD FIX ME */ /* unlock the channel again before we exit */ @@ -1496,17 +1369,9 @@ ftdm_status_t handle_rsc_req(uint32_t suInstId, uint32_t spInstId, uint32_t circ return FTDM_FAIL; } - /* now that we have the right channel...put a lock on it so no-one else can use it */ + /* lock the channel */ 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); - SS7_FUNC_TRACE_EXIT(__FUNCTION__); - SS7_ASSERT; - }; - /* throw the reset flag */ sngss7_set_flag(sngss7_info, FLAG_RESET_RX); @@ -1549,17 +1414,9 @@ ftdm_status_t handle_local_rsc_req(uint32_t suInstId, uint32_t spInstId, uint32_ return FTDM_FAIL; } - /* now that we have the right channel...put a lock on it so no-one else can use it */ + /* lock the channel */ 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); - SS7_FUNC_TRACE_EXIT(__FUNCTION__); - SS7_ASSERT; - }; - /* throw the reset flag */ sngss7_set_flag(sngss7_info, FLAG_RESET_RX); @@ -1602,17 +1459,9 @@ ftdm_status_t handle_rsc_rsp(uint32_t suInstId, uint32_t spInstId, uint32_t circ return FTDM_FAIL; } - /* now that we have the right channel...put a lock on it so no-one else can use it */ + /* lock the channel */ 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); - SS7_FUNC_TRACE_EXIT(__FUNCTION__); - SS7_ASSERT; - }; - switch (ftdmchan->state) { /**********************************************************************/ case FTDM_CHANNEL_STATE_RESTART: @@ -1704,15 +1553,8 @@ ftdm_status_t handle_grs_req(uint32_t suInstId, uint32_t spInstId, uint32_t circ break; } - /* now that we have the right channel...put a lock on it so no-one else can use it */ + /* lock the channel */ 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); - SS7_ASSERT; - }; /* fill in the span structure for this circuit */ sngss7_span = ftdmchan->span->mod_data; @@ -1780,15 +1622,8 @@ ftdm_status_t handle_grs_rsp(uint32_t suInstId, uint32_t spInstId, uint32_t circ break; } - /* now that we have the right channel...put a lock on it so no-one else can use it */ + /* lock the channel */ 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); - SS7_ASSERT; - }; SS7_INFO_CHAN(ftdmchan, "Rx GRA (%d:%d)\n", g_ftdm_sngss7_data.cfg.isupCkt[circuit].cic, @@ -1862,17 +1697,9 @@ ftdm_status_t handle_local_blk(uint32_t suInstId, uint32_t spInstId, uint32_t ci return FTDM_FAIL; } - /* now that we have the right channel...put a lock on it so no-one else can use it */ + /* lock the channel */ 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); - SS7_FUNC_TRACE_EXIT(__FUNCTION__); - SS7_ASSERT; - }; - /* check if the circuit is already blocked or not */ if (sngss7_test_flag(sngss7_info, FLAG_CKT_LC_BLOCK_RX)) { SS7_WARN("Received local BLO on circuit that is already blocked!\n"); @@ -1906,17 +1733,9 @@ ftdm_status_t handle_local_ubl(uint32_t suInstId, uint32_t spInstId, uint32_t ci return FTDM_FAIL; } - /* now that we have the right channel...put a lock on it so no-one else can use it */ + /* lock the channel */ 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); - SS7_FUNC_TRACE_EXIT(__FUNCTION__); - SS7_ASSERT; - }; - /* check if the circuit is already blocked or not */ if (sngss7_test_flag(sngss7_info, FLAG_CKT_LC_UNBLK_RX)) { SS7_WARN("Received local UBL on circuit that is already unblocked!\n"); @@ -1950,17 +1769,9 @@ ftdm_status_t handle_ucic(uint32_t suInstId, uint32_t spInstId, uint32_t circuit return FTDM_FAIL; } - /* now that we have the right channel...put a lock on it so no-one else can use it */ + /* lock the channel */ 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); - SS7_FUNC_TRACE_EXIT(__FUNCTION__); - SS7_ASSERT; - }; - /* throw the ckt block flag */ sngss7_set_flag(sngss7_info, FLAG_CKT_UCIC_BLOCK); @@ -1988,7 +1799,9 @@ ftdm_status_t handle_cgb_req(uint32_t suInstId, uint32_t spInstId, uint32_t circ int byte = 0; int bit = 0; int x; + ftdm_sigmsg_t sigev; + memset(&sigev, 0, sizeof (sigev)); memset(&status[0], '\0', sizeof(status)); /* get the ftdmchan and ss7_chan_data from the circuit */ @@ -2040,22 +1853,17 @@ ftdm_status_t handle_cgb_req(uint32_t suInstId, uint32_t spInstId, uint32_t circ /* loop over the cics starting from circuit until range+1 */ for (x = circuit; x < (circuit + range + 1); x++) { + /* confirm this is a voice channel */ 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; } - /* now that we have the right channel...put a lock on it so no-one else can use it */ + /* lock the channel */ 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); - SS7_ASSERT; - }; #if 0 SS7_ERROR("KONRAD -> circuit=%d, byte=%d, bit=%d, status[byte]=%d, math=%d\n", @@ -2085,6 +1893,15 @@ ftdm_status_t handle_cgb_req(uint32_t suInstId, uint32_t spInstId, uint32_t circ } /* switch (blockType) */ } + sigev.chan_id = ftdmchan->chan_id; + sigev.span_id = ftdmchan->span_id; + sigev.channel = ftdmchan; + + /* bring the sig status down */ + sigev.event_id = FTDM_SIGEVENT_SIGSTATUS_CHANGED; + sigev.sigstatus = FTDM_SIG_STATE_DOWN; + ftdm_span_send_signal(ftdmchan->span, &sigev); + /* unlock the channel again before we exit */ ftdm_mutex_unlock(ftdmchan->mutex); @@ -2123,7 +1940,9 @@ ftdm_status_t handle_cgu_req(uint32_t suInstId, uint32_t spInstId, uint32_t circ int byte = 0; int bit = 0; int x; + ftdm_sigmsg_t sigev; + memset(&sigev, 0, sizeof (sigev)); memset(&status[0], '\0', sizeof(status)); /* get the ftdmchan and ss7_chan_data from the circuit */ @@ -2140,7 +1959,7 @@ ftdm_status_t handle_cgu_req(uint32_t suInstId, uint32_t spInstId, uint32_t circ if ((siStaEvnt->cgsmti.eh.pres == PRSNT_NODEF) && (siStaEvnt->cgsmti.typeInd.pres == PRSNT_NODEF)) { blockType = siStaEvnt->cgsmti.typeInd.val; } else { - SS7_ERROR("Received CGB with no circuit group supervision value on CIC = %d\n", sngss7_info->circuit->cic); + SS7_ERROR("Received CGU with no circuit group supervision value on CIC = %d\n", sngss7_info->circuit->cic); SS7_FUNC_TRACE_EXIT(__FUNCTION__); return FTDM_FAIL; } @@ -2149,7 +1968,7 @@ ftdm_status_t handle_cgu_req(uint32_t suInstId, uint32_t spInstId, uint32_t circ if ((siStaEvnt->rangStat.eh.pres == PRSNT_NODEF) && (siStaEvnt->rangStat.range.pres == PRSNT_NODEF)) { range = siStaEvnt->rangStat.range.val; } else { - SS7_ERROR("Received CGB with no range value on CIC = %d\n", sngss7_info->circuit->cic); + SS7_ERROR("Received CGU with no range value on CIC = %d\n", sngss7_info->circuit->cic); SS7_FUNC_TRACE_EXIT(__FUNCTION__); return FTDM_FAIL; } @@ -2160,7 +1979,7 @@ ftdm_status_t handle_cgu_req(uint32_t suInstId, uint32_t spInstId, uint32_t circ status[x] = siStaEvnt->rangStat.status.val[x]; } } else { - SS7_ERROR("Received CGB with no status value on CIC = %d\n", sngss7_info->circuit->cic); + SS7_ERROR("Received CGU with no status value on CIC = %d\n", sngss7_info->circuit->cic); SS7_FUNC_TRACE_EXIT(__FUNCTION__); return FTDM_FAIL; } @@ -2182,15 +2001,8 @@ ftdm_status_t handle_cgu_req(uint32_t suInstId, uint32_t spInstId, uint32_t circ break; } - /* now that we have the right channel...put a lock on it so no-one else can use it */ + /* lock the channel */ 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); - SS7_ASSERT; - }; if (status[byte] & (1 << bit)) { switch (blockType) { @@ -2210,7 +2022,16 @@ ftdm_status_t handle_cgu_req(uint32_t suInstId, uint32_t spInstId, uint32_t circ break; /**********************************************************************/ } /* switch (blockType) */ - } /* */ + } /* if (status[byte] & (1 << bit)) */ + + sigev.chan_id = ftdmchan->chan_id; + sigev.span_id = ftdmchan->span_id; + sigev.channel = ftdmchan; + + /* bring the sig status down */ + sigev.event_id = FTDM_SIGEVENT_SIGSTATUS_CHANGED; + sigev.sigstatus = FTDM_SIG_STATE_UP; + ftdm_span_send_signal(ftdmchan->span, &sigev); /* unlock the channel again before we exit */ ftdm_mutex_unlock(ftdmchan->mutex); diff --git a/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_logger.c b/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_logger.c index 03f0beb090..3f507d6648 100644 --- a/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_logger.c +++ b/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_logger.c @@ -496,6 +496,12 @@ void handle_sng_isup_alarm(Pst *pst, SiMngmt *sta) /* initalize the msg variable to NULLs */ memset(&msg[0], '\0', sizeof(&msg)); + /* if the event is REMOTE/LOCAL we don't need to print these */ + if ((sta->t.usta.alarm.event == LSI_EVENT_REMOTE) || + (sta->t.usta.alarm.event == LSI_EVENT_LOCAL)) { + return; + } + /* point p to the first spot in msg */ p = &msg[0]; @@ -728,6 +734,8 @@ void handle_sng_isup_alarm(Pst *pst, SiMngmt *sta) DECODE_LSI_EVENT(sta->t.usta.alarm.event), DECODE_LSI_CAUSE(sta->t.usta.alarm.cause)); + return; + } /* handle_isup_alarm */ /******************************************************************************/ 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 a4fee0f862..19f042bc2e 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 @@ -454,9 +454,9 @@ 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) { - ftdm_sigmsg_t sigev; sngss7_chan_data_t *sngss7_info = ftdmchan->call_data; int i = 0; + ftdm_sigmsg_t sigev; memset (&sigev, 0, sizeof (sigev)); @@ -788,14 +788,24 @@ static void ftdm_sangoma_ss7_process_state_change (ftdm_channel_t * ftdmchan) !(sngss7_test_flag (sngss7_info, FLAG_GRP_RESET_TX)) && !(sngss7_test_flag (sngss7_info, FLAG_GRP_RESET_RX))) { - /* check if the sig status is down, and bring it up if it isn't */ - if (!ftdm_test_flag (ftdmchan, FTDM_CHANNEL_SIG_UP)) { - SS7_DEBUG_CHAN(ftdmchan,"All reset flags cleared %s\n", ""); - /* all flags are down so we can bring up the sig status */ - sigev.event_id = FTDM_SIGEVENT_SIGSTATUS_CHANGED; - sigev.sigstatus = FTDM_SIG_STATE_UP; - ftdm_span_send_signal (ftdmchan->span, &sigev); - } + /* now check if there is an active block */ + if (!(sngss7_test_flag(sngss7_info, FLAG_CKT_LC_BLOCK_RX)) && + !(sngss7_test_flag(sngss7_info, FLAG_CKT_MN_BLOCK_RX)) && + !(sngss7_test_flag(sngss7_info, FLAG_CKT_MN_BLOCK_TX)) && + !(sngss7_test_flag(sngss7_info, FLAG_GRP_HW_BLOCK_RX)) && + !(sngss7_test_flag(sngss7_info, FLAG_GRP_HW_BLOCK_TX)) && + !(sngss7_test_flag(sngss7_info, FLAG_GRP_MN_BLOCK_RX)) && + !(sngss7_test_flag(sngss7_info, FLAG_GRP_MN_BLOCK_TX))) { + + /* check if the sig status is down, and bring it up if it isn't */ + if (!ftdm_test_flag (ftdmchan, FTDM_CHANNEL_SIG_UP)) { + SS7_DEBUG_CHAN(ftdmchan,"All reset flags cleared %s\n", ""); + /* all flags are down so we can bring up the sig status */ + sigev.event_id = FTDM_SIGEVENT_SIGSTATUS_CHANGED; + sigev.sigstatus = FTDM_SIG_STATE_UP; + ftdm_span_send_signal (ftdmchan->span, &sigev); + } /* if (!ftdm_test_flag (ftdmchan, FTDM_CHANNEL_SIG_UP)) */ + } /* if !blocked */ } else { SS7_DEBUG_CHAN(ftdmchan,"Reset flags present (0x%X)\n", sngss7_info->flags); @@ -993,6 +1003,11 @@ static void ftdm_sangoma_ss7_process_state_change (ftdm_channel_t * ftdmchan) if (sngss7_test_flag (sngss7_info, FLAG_CKT_MN_BLOCK_RX)) { SS7_DEBUG_CHAN(ftdmchan, "Processing CKT_MN_BLOCK_RX flag %s\n", ""); + /* bring the sig status down */ + sigev.event_id = FTDM_SIGEVENT_SIGSTATUS_CHANGED; + sigev.sigstatus = FTDM_SIG_STATE_DOWN; + ftdm_span_send_signal(ftdmchan->span, &sigev); + /* send a BLA */ ft_to_sngss7_bla (ftdmchan); @@ -1006,6 +1021,11 @@ static void ftdm_sangoma_ss7_process_state_change (ftdm_channel_t * ftdmchan) /* clear the unblock flag */ sngss7_clear_flag (sngss7_info, FLAG_CKT_MN_UNBLK_RX); + /* bring the sig status up */ + sigev.event_id = FTDM_SIGEVENT_SIGSTATUS_CHANGED; + sigev.sigstatus = FTDM_SIG_STATE_UP; + ftdm_span_send_signal(ftdmchan->span, &sigev); + /* send a uba */ ft_to_sngss7_uba (ftdmchan); @@ -1017,6 +1037,11 @@ static void ftdm_sangoma_ss7_process_state_change (ftdm_channel_t * ftdmchan) if (sngss7_test_flag (sngss7_info, FLAG_CKT_MN_BLOCK_TX)) { SS7_DEBUG_CHAN(ftdmchan, "Processing CKT_MN_BLOCK_TX flag %s\n", ""); + /* bring the sig status down */ + sigev.event_id = FTDM_SIGEVENT_SIGSTATUS_CHANGED; + sigev.sigstatus = FTDM_SIG_STATE_DOWN; + ftdm_span_send_signal(ftdmchan->span, &sigev); + /* send a blo */ ft_to_sngss7_blo (ftdmchan); @@ -1030,6 +1055,11 @@ static void ftdm_sangoma_ss7_process_state_change (ftdm_channel_t * ftdmchan) /* clear the unblock flag */ sngss7_clear_flag (sngss7_info, FLAG_CKT_MN_UNBLK_TX); + /* bring the sig status up */ + sigev.event_id = FTDM_SIGEVENT_SIGSTATUS_CHANGED; + sigev.sigstatus = FTDM_SIG_STATE_UP; + ftdm_span_send_signal(ftdmchan->span, &sigev); + /* send a ubl */ ft_to_sngss7_ubl (ftdmchan); @@ -1403,6 +1433,9 @@ static FIO_CONFIGURE_SPAN_SIGNALING_FUNCTION(ftdm_sangoma_ss7_span_config) static FIO_SIG_LOAD_FUNCTION(ftdm_sangoma_ss7_init) { /*this function is called by the FT-core to load the signaling module */ + uint32_t major = 0; + uint32_t minor = 0; + uint32_t build = 0; ftdm_log (FTDM_LOG_INFO, "Loading ftmod_sangoma_ss7...\n"); @@ -1452,6 +1485,10 @@ static FIO_SIG_LOAD_FUNCTION(ftdm_sangoma_ss7_init) /* initalize sng_ss7 library */ sng_isup_init (&sng_event); + /* print the version of the library being used */ + sng_isup_version(&major, &minor, &build); + SS7_INFO("Loaded LibSng-SS7 %d.%d.%d\n", major, minor, build); + /* crash on assert fail */ ftdm_global_set_crash_policy (FTDM_CRASH_ON_ASSERT); 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 34abd265a6..8b3f9d8424 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 @@ -199,7 +199,8 @@ void ft_to_sngss7_iam (ftdm_channel_t * ftdmchan) &iam, 0); - SS7_INFO_CHAN(ftdmchan,"Tx IAM clg = \"%s\", cld = \"%s\"\n", + SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Tx IAM clg = \"%s\", cld = \"%s\"\n", + sngss7_info->circuit->cic, ftdmchan->caller_data.cid_num.digits, ftdmchan->caller_data.dnis.digits); @@ -250,7 +251,7 @@ void ft_to_sngss7_acm (ftdm_channel_t * ftdmchan) &acm, ADDRCMPLT); - SS7_MSG_TRACE(ftdmchan, sngss7_info, "Tx ACM\n"); + SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Tx ACM\n", sngss7_info->circuit->cic); SS7_FUNC_TRACE_EXIT (__FUNCTION__); return; @@ -274,7 +275,7 @@ void ft_to_sngss7_anm (ftdm_channel_t * ftdmchan) &anm, 5); - SS7_MSG_TRACE(ftdmchan, sngss7_info, "Tx ANM\n"); + SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Tx ANM\n", sngss7_info->circuit->cic); SS7_FUNC_TRACE_EXIT (__FUNCTION__); return; @@ -307,7 +308,9 @@ void ft_to_sngss7_rel (ftdm_channel_t * ftdmchan) sngss7_info->circuit->id, &rel); - SS7_MSG_TRACE(ftdmchan, sngss7_info, "Tx REL\n"); + SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Tx REL cause=%d \n", + sngss7_info->circuit->cic, + ftdmchan->caller_data.hangup_cause ); SS7_FUNC_TRACE_EXIT (__FUNCTION__); return; @@ -330,7 +333,7 @@ void ft_to_sngss7_rlc (ftdm_channel_t * ftdmchan) sngss7_info->circuit->id, &rlc); - SS7_MSG_TRACE(ftdmchan, sngss7_info, "Tx RLC\n"); + SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Tx RLC\n", sngss7_info->circuit->cic); SS7_FUNC_TRACE_EXIT (__FUNCTION__); return; @@ -351,7 +354,7 @@ void ft_to_sngss7_rsc (ftdm_channel_t * ftdmchan) SIT_STA_CIRRESREQ, NULL); - SS7_MSG_TRACE(ftdmchan, sngss7_info, "Tx RSC\n"); + SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Tx RSC\n", sngss7_info->circuit->cic); SS7_FUNC_TRACE_EXIT (__FUNCTION__); return; @@ -372,7 +375,7 @@ void ft_to_sngss7_rsca (ftdm_channel_t * ftdmchan) SIT_STA_CIRRESRSP, NULL); - SS7_MSG_TRACE(ftdmchan, sngss7_info, "Tx RSC-RLC\n"); + SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Tx RSC-RLC\n", sngss7_info->circuit->cic); SS7_FUNC_TRACE_EXIT (__FUNCTION__); return; @@ -393,7 +396,7 @@ void ft_to_sngss7_blo (ftdm_channel_t * ftdmchan) SIT_STA_CIRBLOREQ, NULL); - SS7_MSG_TRACE(ftdmchan, sngss7_info, "Tx BLO\n"); + SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Tx BLO\n", sngss7_info->circuit->cic); SS7_FUNC_TRACE_EXIT (__FUNCTION__); return; @@ -414,7 +417,7 @@ void ft_to_sngss7_bla (ftdm_channel_t * ftdmchan) SIT_STA_CIRBLORSP, NULL); - SS7_MSG_TRACE(ftdmchan, sngss7_info, "Tx BLA\n"); + SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Tx BLA\n", sngss7_info->circuit->cic); SS7_FUNC_TRACE_EXIT (__FUNCTION__); return; @@ -436,7 +439,7 @@ ft_to_sngss7_ubl (ftdm_channel_t * ftdmchan) SIT_STA_CIRUBLREQ, NULL); - SS7_MSG_TRACE(ftdmchan, sngss7_info, "Tx UBL\n"); + SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Tx UBL\n", sngss7_info->circuit->cic); SS7_FUNC_TRACE_EXIT (__FUNCTION__); return; @@ -457,7 +460,7 @@ void ft_to_sngss7_uba (ftdm_channel_t * ftdmchan) SIT_STA_CIRUBLRSP, NULL); - SS7_MSG_TRACE(ftdmchan, sngss7_info, "Tx UBA\n"); + SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Tx UBA\n", sngss7_info->circuit->cic); SS7_FUNC_TRACE_EXIT (__FUNCTION__); return; @@ -478,7 +481,7 @@ void ft_to_sngss7_lpa (ftdm_channel_t * ftdmchan) SIT_STA_LOOPBACKACK, NULL); - SS7_MSG_TRACE(ftdmchan, sngss7_info, "Tx LPA\n"); + SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Tx LPA\n", sngss7_info->circuit->cic); SS7_FUNC_TRACE_EXIT (__FUNCTION__); return; @@ -519,7 +522,8 @@ void ft_to_sngss7_gra (ftdm_channel_t * ftdmchan) SIT_STA_GRSRSP, &gra); - SS7_INFO_CHAN(ftdmchan, "Tx GRA (%d:%d)\n", + SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Tx GRA (%d:%d)\n", + sngss7_info->circuit->cic, sngss7_info->circuit->cic, (sngss7_info->circuit->cic + sngss7_span->rx_grs.range)); @@ -551,7 +555,8 @@ void ft_to_sngss7_grs (ftdm_channel_t * ftdmchan) SIT_STA_GRSREQ, &grs); - SS7_INFO_CHAN(ftdmchan, "Tx GRS (%d:%d)\n", + SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Tx GRS (%d:%d)\n", + sngss7_info->circuit->cic, sngss7_info->circuit->cic, (sngss7_info->circuit->cic + sngss7_span->tx_grs.range)); @@ -596,7 +601,8 @@ void ft_to_sngss7_cgba(ftdm_channel_t * ftdmchan) SIT_STA_CGBRSP, &cgba); - SS7_INFO_CHAN(ftdmchan, "Tx CGBA (%d:%d)\n", + SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Tx CGBA (%d:%d)\n", + sngss7_info->circuit->cic, sngss7_info->circuit->cic, (sngss7_info->circuit->cic + sngss7_span->rx_cgb.range)); @@ -644,7 +650,8 @@ void ft_to_sngss7_cgua(ftdm_channel_t * ftdmchan) SIT_STA_CGURSP, &cgua); - SS7_INFO_CHAN(ftdmchan, "Tx CGUA (%d:%d)\n", + SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Tx CGUA (%d:%d)\n", + sngss7_info->circuit->cic, sngss7_info->circuit->cic, (sngss7_info->circuit->cic + sngss7_span->rx_cgu.range)); @@ -693,7 +700,8 @@ void ft_to_sngss7_cgb(ftdm_channel_t * ftdmchan) SIT_STA_CGBREQ, &cgb); - SS7_INFO_CHAN(ftdmchan, "Tx CGB (%d:%d)\n", + SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Tx CGB (%d:%d)\n", + sngss7_info->circuit->cic, sngss7_info->circuit->cic, (sngss7_info->circuit->cic + sngss7_span->tx_cgb.range)); @@ -742,7 +750,8 @@ void ft_to_sngss7_cgu(ftdm_channel_t * ftdmchan) SIT_STA_CGUREQ, &cgu); - SS7_INFO_CHAN(ftdmchan, "Tx CGU (%d:%d)\n", + SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Tx CGU (%d:%d)\n", + sngss7_info->circuit->cic, sngss7_info->circuit->cic, (sngss7_info->circuit->cic + sngss7_span->tx_cgu.range)); 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 694e9a4ed8..aaffeb0a36 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 @@ -464,7 +464,7 @@ 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); - SS7_ASSERT; + continue; } /* lock the channel */ @@ -476,61 +476,61 @@ ftdm_status_t check_if_rx_grs_processed(ftdm_span_t *ftdmspan) if (!sngss7_test_flag(sngss7_info, FLAG_GRP_RESET_RX_DN)) { /* this channel is still resetting...do nothing */ goto GRS_UNLOCK_ALL; - } /* if (!sngss7_test_flag(sngss7_info, FLAG_GRP_RESET_RX_DN)) */ - } else { - /* state change pending */ - goto GRS_UNLOCK_ALL; - } - } /* for ( i = circuit; i < (circuit + range + 1); i++) */ + } /* if (!sngss7_test_flag(sngss7_info, FLAG_GRP_RESET_RX_DN)) */ + } else { + /* state change pending */ + goto GRS_UNLOCK_ALL; + } + } /* for ( i = circuit; i < (circuit + range + 1); i++) */ - SS7_DEBUG("All circuits out of reset for GRS: circuit=%d, range=%d\n", - sngss7_span->rx_grs.circuit, - sngss7_span->rx_grs.range); + SS7_DEBUG("All circuits out of reset for GRS: circuit=%d, range=%d\n", + sngss7_span->rx_grs.circuit, + sngss7_span->rx_grs.range); - /* check all the circuits in the range to see if they are done resetting */ - for ( i = sngss7_span->rx_grs.circuit; i < (sngss7_span->rx_grs.circuit + sngss7_span->rx_grs.range + 1); i++) { + /* check all the circuits in the range to see if they are done resetting */ + 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); - SS7_ASSERT; - } + /* 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); + SS7_ASSERT; + } - /* throw the GRP reset flag complete flag */ - sngss7_set_flag(sngss7_info, FLAG_GRP_RESET_RX_CMPLT); + /* throw the GRP reset flag complete flag */ + sngss7_set_flag(sngss7_info, FLAG_GRP_RESET_RX_CMPLT); - /* move the channel to the down state */ - ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_DOWN); + /* move the channel to the down state */ + ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_DOWN); - /* update the status map if the ckt is in blocked state */ - if ((sngss7_test_flag(sngss7_info, FLAG_CKT_MN_BLOCK_RX)) || - (sngss7_test_flag(sngss7_info, FLAG_CKT_MN_BLOCK_TX)) || - (sngss7_test_flag(sngss7_info, FLAG_GRP_MN_BLOCK_RX)) || - (sngss7_test_flag(sngss7_info, FLAG_GRP_MN_BLOCK_RX))) { - - sngss7_span->rx_grs.status[byte] = (sngss7_span->rx_grs.status[byte] | (1 << bit)); - } /* if blocked */ - - /* update the bit and byte counter*/ - bit ++; - if (bit == 8) { - byte++; - bit = 0; - } - } /* for ( i = circuit; i < (circuit + range + 1); i++) */ + /* update the status map if the ckt is in blocked state */ + if ((sngss7_test_flag(sngss7_info, FLAG_CKT_MN_BLOCK_RX)) || + (sngss7_test_flag(sngss7_info, FLAG_CKT_MN_BLOCK_TX)) || + (sngss7_test_flag(sngss7_info, FLAG_GRP_MN_BLOCK_RX)) || + (sngss7_test_flag(sngss7_info, FLAG_GRP_MN_BLOCK_RX))) { + + sngss7_span->rx_grs.status[byte] = (sngss7_span->rx_grs.status[byte] | (1 << bit)); + } /* if blocked */ + + /* update the bit and byte counter*/ + bit ++; + if (bit == 8) { + byte++; + bit = 0; + } + } /* for ( i = circuit; i < (circuit + range + 1); i++) */ GRS_UNLOCK_ALL: - 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); - SS7_ASSERT; - } - - /* unlock the channel */ - ftdm_mutex_unlock(ftdmchan->mutex); + 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; } + /* unlock the channel */ + ftdm_mutex_unlock(ftdmchan->mutex); + } + return FTDM_SUCCESS; } From 696becc093a8faf05ac398d8e1a2d433abbbf6f7 Mon Sep 17 00:00:00 2001 From: Moises Silva Date: Tue, 21 Sep 2010 07:19:56 -0400 Subject: [PATCH 03/15] freetdm: add force hangup timer and refactor scheduling code --- libs/freetdm/src/ftdm_io.c | 37 ++++++++++ libs/freetdm/src/ftdm_sched.c | 70 +++++++++---------- .../ftmod_sangoma_isdn/ftmod_sangoma_isdn.h | 2 +- .../ftmod_sangoma_isdn_stack_hndl.c | 2 +- libs/freetdm/src/include/private/ftdm_core.h | 1 + libs/freetdm/src/include/private/ftdm_sched.h | 14 ++-- 6 files changed, 83 insertions(+), 43 deletions(-) diff --git a/libs/freetdm/src/ftdm_io.c b/libs/freetdm/src/ftdm_io.c index 6991e9ab9b..84ce1ac521 100644 --- a/libs/freetdm/src/ftdm_io.c +++ b/libs/freetdm/src/ftdm_io.c @@ -102,6 +102,7 @@ static struct { ftdm_mutex_t *mutex; ftdm_mutex_t *span_mutex; ftdm_mutex_t *group_mutex; + ftdm_sched_t *timingsched; uint32_t span_index; uint32_t group_index; uint32_t running; @@ -2002,6 +2003,9 @@ static ftdm_status_t call_hangup(ftdm_channel_t *chan, const char *file, const c /* make user's life easier, and just ignore double hangup requests */ return FTDM_SUCCESS; } + if (chan->hangup_timer) { + ftdm_sched_cancel_timer(globals.timingsched, chan->hangup_timer); + } ftdm_channel_set_state(file, func, line, chan, FTDM_CHANNEL_STATE_HANGUP, 1); } else { /* the signaling stack did not touch the state, @@ -2283,6 +2287,9 @@ FT_DECLARE(ftdm_status_t) ftdm_channel_done(ftdm_channel_t *ftdmchan) close_dtmf_debug(ftdmchan); #endif ftdm_channel_clear_vars(ftdmchan); + if (ftdmchan->hangup_timer) { + ftdm_sched_cancel_timer(globals.timingsched, ftdmchan->hangup_timer); + } ftdmchan->init_state = FTDM_CHANNEL_STATE_DOWN; ftdmchan->state = FTDM_CHANNEL_STATE_DOWN; @@ -4601,6 +4608,21 @@ FT_DECLARE(ftdm_status_t) ftdm_span_trigger_signals(const ftdm_span_t *span) return FTDM_SUCCESS; } + +static void execute_safety_hangup(void *data) +{ + ftdm_channel_t *fchan = data; + ftdm_channel_lock(fchan); + fchan->hangup_timer = 0; + if (fchan->state == FTDM_CHANNEL_STATE_TERMINATING) { + ftdm_log_chan_msg(fchan, FTDM_LOG_CRIT, "Forcing hangup\n"); + ftdm_channel_call_hangup(fchan); + } else { + ftdm_log_chan(fchan, FTDM_LOG_CRIT, "Not performing safety hangup, channel state is %s\n", ftdm_channel_state2str(fchan->state)); + } + ftdm_channel_unlock(fchan); +} + FT_DECLARE(ftdm_status_t) ftdm_span_send_signal(ftdm_span_t *span, ftdm_sigmsg_t *sigmsg) { if (sigmsg->channel) { @@ -4634,6 +4656,11 @@ FT_DECLARE(ftdm_status_t) ftdm_span_send_signal(ftdm_span_t *span, ftdm_sigmsg_t ftdm_log_chan_msg(sigmsg->channel, FTDM_LOG_DEBUG, "Ignoring SIGEVENT_STOP since user already requested hangup\n"); goto done; } + if (sigmsg->channel->state == FTDM_CHANNEL_STATE_TERMINATING) { + ftdm_log_chan_msg(sigmsg->channel, FTDM_LOG_DEBUG, "Scheduling safety hangup timer\n"); + /* if the user does not move us to hangup in 2 seconds, we will do it ourselves */ + ftdm_sched_timer(globals.timingsched, "safety-hangup", 2000, execute_safety_hangup, sigmsg->channel, &sigmsg->channel->hangup_timer); + } break; default: @@ -4755,6 +4782,14 @@ FT_DECLARE(ftdm_status_t) ftdm_global_init(void) ftdm_mutex_create(&globals.span_mutex); ftdm_mutex_create(&globals.group_mutex); ftdm_sched_global_init(); + if (ftdm_sched_create(&globals.timingsched, "freetdm-master") != FTDM_SUCCESS) { + ftdm_log(FTDM_LOG_CRIT, "Failed to create master timing schedule context\n"); + return FTDM_FAIL; + } + if (ftdm_sched_free_run(globals.timingsched) != FTDM_SUCCESS) { + ftdm_log(FTDM_LOG_CRIT, "Failed to run master timing schedule context\n"); + return FTDM_FAIL; + } globals.running = 1; return FTDM_SUCCESS; } @@ -4807,6 +4842,8 @@ FT_DECLARE(ftdm_status_t) ftdm_global_destroy(void) globals.running = 0; + ftdm_sched_destroy(&globals.timingsched); + ftdm_cpu_monitor_stop(); globals.span_index = 0; diff --git a/libs/freetdm/src/ftdm_sched.c b/libs/freetdm/src/ftdm_sched.c index 5aacc202bf..340f442c64 100644 --- a/libs/freetdm/src/ftdm_sched.c +++ b/libs/freetdm/src/ftdm_sched.c @@ -34,6 +34,8 @@ #include "private/ftdm_core.h" +typedef struct ftdm_timer ftdm_timer_t; + static struct { ftdm_sched_t *freeruns; ftdm_mutex_t *mutex; @@ -42,6 +44,7 @@ static struct { struct ftdm_sched { char name[80]; + ftdm_timer_id_t currid; ftdm_mutex_t *mutex; ftdm_timer_t *timers; int freerun; @@ -51,6 +54,7 @@ struct ftdm_sched { struct ftdm_timer { char name[80]; + ftdm_timer_id_t id; #ifdef __linux__ struct timeval time; #endif @@ -191,6 +195,7 @@ FT_DECLARE(ftdm_status_t) ftdm_sched_create(ftdm_sched_t **sched, const char *na } ftdm_set_string(newsched->name, name); + newsched->currid = 1; *sched = newsched; ftdm_log(FTDM_LOG_DEBUG, "Created schedule %s\n", name); @@ -219,12 +224,13 @@ FT_DECLARE(ftdm_status_t) ftdm_sched_run(ftdm_sched_t *sched) int rc = -1; void *data; struct timeval now; + ftdm_assert_return(sched != NULL, FTDM_EINVAL, "sched is null!\n"); - ftdm_mutex_lock(sched->mutex); - tryagain: + ftdm_mutex_lock(sched->mutex); + rc = gettimeofday(&now, NULL); if (rc == -1) { ftdm_log(FTDM_LOG_ERROR, "Failed to retrieve time of day\n"); @@ -257,11 +263,16 @@ tryagain: runtimer->prev->next = runtimer->next; } + runtimer->id = 0; ftdm_safe_free(runtimer); + /* avoid deadlocks by releasing the sched lock before triggering callbacks */ + ftdm_mutex_unlock(sched->mutex); + callback(data); /* after calling a callback we must start the scanning again since the - * callback may have added or cancelled timers to the linked list */ + * callback or some other thread may have added or cancelled timers to + * the linked list */ goto tryagain; } } @@ -283,7 +294,7 @@ done: } FT_DECLARE(ftdm_status_t) ftdm_sched_timer(ftdm_sched_t *sched, const char *name, - int ms, ftdm_sched_callback_t callback, void *data, ftdm_timer_t **timer) + int ms, ftdm_sched_callback_t callback, void *data, ftdm_timer_id_t *timerid) { ftdm_status_t status = FTDM_FAIL; #ifdef __linux__ @@ -296,8 +307,8 @@ FT_DECLARE(ftdm_status_t) ftdm_sched_timer(ftdm_sched_t *sched, const char *name ftdm_assert_return(callback != NULL, FTDM_EINVAL, "sched callback is null!\n"); ftdm_assert_return(ms > 0, FTDM_EINVAL, "milliseconds must be bigger than 0!\n"); - if (timer) { - *timer = NULL; + if (timerid) { + *timerid = 0; } rc = gettimeofday(&now, NULL); @@ -312,6 +323,8 @@ FT_DECLARE(ftdm_status_t) ftdm_sched_timer(ftdm_sched_t *sched, const char *name if (!newtimer) { goto done; } + newtimer->id = sched->currid; + sched->currid++; ftdm_set_string(newtimer->name, name); newtimer->callback = callback; @@ -332,9 +345,10 @@ FT_DECLARE(ftdm_status_t) ftdm_sched_timer(ftdm_sched_t *sched, const char *name sched->timers = newtimer; } - if (timer) { - *timer = newtimer; + if (timerid) { + *timerid = newtimer->id; } + status = FTDM_SUCCESS; done: @@ -418,53 +432,37 @@ done: return status; } -FT_DECLARE(ftdm_status_t) ftdm_sched_cancel_timer(ftdm_sched_t *sched, ftdm_timer_t **intimer) +FT_DECLARE(ftdm_status_t) ftdm_sched_cancel_timer(ftdm_sched_t *sched, ftdm_timer_id_t timerid) { ftdm_status_t status = FTDM_FAIL; ftdm_timer_t *timer; ftdm_assert_return(sched != NULL, FTDM_EINVAL, "sched is null!\n"); - ftdm_assert_return(intimer != NULL, FTDM_EINVAL, "timer is null!\n"); - ftdm_assert_return(*intimer != NULL, FTDM_EINVAL, "timer is null!\n"); + + if (!timerid) { + return FTDM_SUCCESS; + } ftdm_mutex_lock(sched->mutex); - /* special case where the cancelled timer is the head */ - if (*intimer == sched->timers) { - timer = *intimer; - /* the timer next is the new head (even if that means the new head will be NULL)*/ - sched->timers = timer->next; - /* if there is a new head, clean its prev member */ - if (sched->timers) { - sched->timers->prev = NULL; - } - /* free the old head */ - ftdm_safe_free(timer); - status = FTDM_SUCCESS; - *intimer = NULL; - goto done; - } - - /* look for the timer and destroy it (we know now that is not head, se we start at the next member after head) */ - for (timer = sched->timers->next; timer; timer = timer->next) { - if (timer == *intimer) { + /* look for the timer and destroy it */ + for (timer = sched->timers; timer; timer = timer->next) { + if (timer->id == timerid) { + if (timer == sched->timers) { + /* it's the head timer, put a new head */ + sched->timers = timer->next; + } if (timer->prev) { timer->prev->next = timer->next; } if (timer->next) { timer->next->prev = timer->prev; } - ftdm_log(FTDM_LOG_DEBUG, "cancelled timer %s\n", timer->name); ftdm_safe_free(timer); status = FTDM_SUCCESS; - *intimer = NULL; break; } } -done: - if (status == FTDM_FAIL) { - ftdm_log(FTDM_LOG_ERROR, "Could not find timer %s to cancel it\n", (*intimer)->name); - } ftdm_mutex_unlock(sched->mutex); diff --git a/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn.h b/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn.h index cd96a18fce..ae6c0d92f7 100644 --- a/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn.h +++ b/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn.h @@ -156,7 +156,7 @@ typedef struct sngisdn_chan_data { uint8_t globalFlg; sngisdn_glare_data_t glare; - ftdm_timer_t *timers[SNGISDN_NUM_TIMERS]; + ftdm_timer_id_t timers[SNGISDN_NUM_TIMERS]; } sngisdn_chan_data_t; /* Span specific data */ diff --git a/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_stack_hndl.c b/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_stack_hndl.c index e2e67eed19..d63ee4cdfe 100644 --- a/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_stack_hndl.c +++ b/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_stack_hndl.c @@ -709,7 +709,7 @@ void sngisdn_process_fac_ind (sngisdn_event_data_t *sngisdn_event) ftdm_log_chan_msg(ftdmchan, FTDM_LOG_WARNING, "Failed to retrieve Caller Name from Facility IE\n"); } /* Cancel facility timeout */ - ftdm_sched_cancel_timer(signal_data->sched, &sngisdn_info->timers[SNGISDN_TIMER_FACILITY]); + ftdm_sched_cancel_timer(signal_data->sched, sngisdn_info->timers[SNGISDN_TIMER_FACILITY]); } ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_RING); diff --git a/libs/freetdm/src/include/private/ftdm_core.h b/libs/freetdm/src/include/private/ftdm_core.h index d8947f6de4..a701c1383d 100644 --- a/libs/freetdm/src/include/private/ftdm_core.h +++ b/libs/freetdm/src/include/private/ftdm_core.h @@ -425,6 +425,7 @@ struct ftdm_channel { float txgain; int availability_rate; void *user_private; + ftdm_timer_id_t hangup_timer; #ifdef FTDM_DEBUG_DTMF ftdm_dtmf_debug_t dtmfdbg; #endif diff --git a/libs/freetdm/src/include/private/ftdm_sched.h b/libs/freetdm/src/include/private/ftdm_sched.h index 0951d050a7..9a222896f5 100644 --- a/libs/freetdm/src/include/private/ftdm_sched.h +++ b/libs/freetdm/src/include/private/ftdm_sched.h @@ -44,8 +44,8 @@ extern "C" { #define FTDM_MICROSECONDS_PER_SECOND 1000000 typedef struct ftdm_sched ftdm_sched_t; -typedef struct ftdm_timer ftdm_timer_t; typedef void (*ftdm_sched_callback_t)(void *data); +typedef uint64_t ftdm_timer_id_t; /*! \brief Create a new scheduling context */ FT_DECLARE(ftdm_status_t) ftdm_sched_create(ftdm_sched_t **sched, const char *name); @@ -62,18 +62,22 @@ FT_DECLARE(ftdm_status_t) ftdm_sched_free_run(ftdm_sched_t *sched); * \param name Timer name, typically unique but is not required to be unique, any null terminated string is fine (required) * \param callback The callback to call upon timer expiration (required) * \param data Optional data to pass to the callback - * \param timer The timer that was created, it can be NULL if you dont care, - * but you need this if you want to be able to cancel the timer with ftdm_sched_cancel_timer + * \param timer Timer id pointer to store the id of the newly created timer. It can be null + * if you do not need to know the id, but you need this if you want to be able + * to cancel the timer with ftdm_sched_cancel_timer */ FT_DECLARE(ftdm_status_t) ftdm_sched_timer(ftdm_sched_t *sched, const char *name, - int ms, ftdm_sched_callback_t callback, void *data, ftdm_timer_t **timer); + int ms, ftdm_sched_callback_t callback, void *data, ftdm_timer_id_t *timer); /*! * \brief Cancel the timer + * Note that there is a race between cancelling and triggering a timer. + * By the time you call this function the timer may be about to be triggered. + * This is specially true with timers in free run schedule. * \param sched The scheduling context (required) * \param timer The timer to cancel (required) */ -FT_DECLARE(ftdm_status_t) ftdm_sched_cancel_timer(ftdm_sched_t *sched, ftdm_timer_t **timer); +FT_DECLARE(ftdm_status_t) ftdm_sched_cancel_timer(ftdm_sched_t *sched, ftdm_timer_id_t timer); /*! \brief Destroy the context and all of the scheduled timers in it */ FT_DECLARE(ftdm_status_t) ftdm_sched_destroy(ftdm_sched_t **sched); From b3f9bfcba56c42480e61d9b9a02a0996a02cf87d Mon Sep 17 00:00:00 2001 From: Moises Silva Date: Tue, 21 Sep 2010 09:34:04 -0400 Subject: [PATCH 04/15] freetdm: define safety hangup timer and use internal hangup function --- libs/freetdm/src/ftdm_io.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/libs/freetdm/src/ftdm_io.c b/libs/freetdm/src/ftdm_io.c index 84ce1ac521..97aa01bca0 100644 --- a/libs/freetdm/src/ftdm_io.c +++ b/libs/freetdm/src/ftdm_io.c @@ -50,6 +50,7 @@ #endif #include "ftdm_cpu_monitor.h" +#define FORCE_HANGUP_TIMER 3000 #define SPAN_PENDING_CHANS_QUEUE_SIZE 1000 #define SPAN_PENDING_SIGNALS_QUEUE_SIZE 1000 #define FTDM_READ_TRACE_INDEX 0 @@ -4615,8 +4616,8 @@ static void execute_safety_hangup(void *data) ftdm_channel_lock(fchan); fchan->hangup_timer = 0; if (fchan->state == FTDM_CHANNEL_STATE_TERMINATING) { - ftdm_log_chan_msg(fchan, FTDM_LOG_CRIT, "Forcing hangup\n"); - ftdm_channel_call_hangup(fchan); + ftdm_log_chan(fchan, FTDM_LOG_CRIT, "Forcing hangup since the user did not confirmed our hangup after %dms\n", FORCE_HANGUP_TIMER); + call_hangup(fchan, __FILE__, __FUNCTION__, __LINE__); } else { ftdm_log_chan(fchan, FTDM_LOG_CRIT, "Not performing safety hangup, channel state is %s\n", ftdm_channel_state2str(fchan->state)); } @@ -4659,7 +4660,7 @@ FT_DECLARE(ftdm_status_t) ftdm_span_send_signal(ftdm_span_t *span, ftdm_sigmsg_t if (sigmsg->channel->state == FTDM_CHANNEL_STATE_TERMINATING) { ftdm_log_chan_msg(sigmsg->channel, FTDM_LOG_DEBUG, "Scheduling safety hangup timer\n"); /* if the user does not move us to hangup in 2 seconds, we will do it ourselves */ - ftdm_sched_timer(globals.timingsched, "safety-hangup", 2000, execute_safety_hangup, sigmsg->channel, &sigmsg->channel->hangup_timer); + ftdm_sched_timer(globals.timingsched, "safety-hangup", FORCE_HANGUP_TIMER, execute_safety_hangup, sigmsg->channel, &sigmsg->channel->hangup_timer); } break; From baead3ddf0abc03c7986ebfd33ecfbfd304781d7 Mon Sep 17 00:00:00 2001 From: Moises Silva Date: Tue, 21 Sep 2010 09:46:33 -0400 Subject: [PATCH 05/15] freetdm: handle timer id wrap-around --- libs/freetdm/src/ftdm_sched.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/libs/freetdm/src/ftdm_sched.c b/libs/freetdm/src/ftdm_sched.c index 340f442c64..be21696d71 100644 --- a/libs/freetdm/src/ftdm_sched.c +++ b/libs/freetdm/src/ftdm_sched.c @@ -325,6 +325,13 @@ FT_DECLARE(ftdm_status_t) ftdm_sched_timer(ftdm_sched_t *sched, const char *name } newtimer->id = sched->currid; sched->currid++; + if (!sched->currid) { + ftdm_log(FTDM_LOG_NOTICE, "Timer id wrap around for sched %s\n", sched->name); + /* we do not want currid to be zero since is an invalid id + * TODO: check that currid does not exists already in the context, it'd be insane + * though, having a timer to live all that time */ + sched->currid++; + } ftdm_set_string(newtimer->name, name); newtimer->callback = callback; From a329bf12b70e5c06c496c60f2f71e1d3d42bb7c8 Mon Sep 17 00:00:00 2001 From: David Yat Sin Date: Fri, 17 Sep 2010 15:08:15 -0400 Subject: [PATCH 06/15] Added handler for case where remote switch misses our CONNECT message Fix for sending wrong address for sng_isdn_retrieve_facility_caller_name Minor fixes --- .../ftmod_sangoma_isdn_stack_hndl.c | 54 +++++++++++-------- 1 file changed, 33 insertions(+), 21 deletions(-) diff --git a/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_stack_hndl.c b/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_stack_hndl.c index e2e67eed19..e8ba3879e5 100644 --- a/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_stack_hndl.c +++ b/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_stack_hndl.c @@ -131,14 +131,12 @@ void sngisdn_process_con_ind (sngisdn_event_data_t *sngisdn_event) } - if (conEvnt->facilityStr.eh.pres) { + if (signal_data->facility == SNGISDN_OPT_TRUE && conEvnt->facilityStr.eh.pres) { /* Verify whether the Caller Name will come in a subsequent FACILITY message */ uint16_t ret_val; - uint8_t facility_str[255]; char retrieved_str[255]; - memcpy(facility_str, (uint8_t*)&conEvnt->facilityStr.facilityStr.val, conEvnt->facilityStr.facilityStr.len); - - ret_val = sng_isdn_retrieve_facility_caller_name(facility_str, conEvnt->facilityStr.facilityStr.len, retrieved_str); + + ret_val = sng_isdn_retrieve_facility_caller_name(conEvnt->facilityStr.facilityStr.val, conEvnt->facilityStr.facilityStr.len, retrieved_str); /* return values for "sng_isdn_retrieve_facility_information_following": If there will be no information following, or fails to decode IE, returns -1 @@ -702,14 +700,23 @@ void sngisdn_process_fac_ind (sngisdn_event_data_t *sngisdn_event) case FTDM_CHANNEL_STATE_GET_CALLERID: /* Update the caller ID Name */ if (facEvnt->facElmt.facStr.pres) { - uint8_t facility_str[255]; - memcpy(facility_str, (uint8_t*)&facEvnt->facElmt.facStr.val, facEvnt->facElmt.facStr.len); char retrieved_str[255]; - if (sng_isdn_retrieve_facility_caller_name(facility_str, facEvnt->facElmt.facStr.len, retrieved_str) != FTDM_SUCCESS) { + + /* return values for "sng_isdn_retrieve_facility_information_following": + If there will be no information following, or fails to decode IE, returns -1 + If there will be no information following, but current FACILITY IE contains a caller name, returns 0 + If there will be information following, returns 1 + */ + + if (sng_isdn_retrieve_facility_caller_name(&facEvnt->facElmt.facStr.val[2], facEvnt->facElmt.facStr.len, retrieved_str) == 0) { + strcpy(ftdmchan->caller_data.cid_name, retrieved_str); + } else { ftdm_log_chan_msg(ftdmchan, FTDM_LOG_WARNING, "Failed to retrieve Caller Name from Facility IE\n"); } - /* Cancel facility timeout */ - ftdm_sched_cancel_timer(signal_data->sched, &sngisdn_info->timers[SNGISDN_TIMER_FACILITY]); + if (signal_data->facility_timeout) { + /* Cancel facility timeout */ + ftdm_sched_cancel_timer(signal_data->sched, &sngisdn_info->timers[SNGISDN_TIMER_FACILITY]); + } } ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_RING); @@ -884,6 +891,22 @@ void sngisdn_process_sta_cfm (sngisdn_event_data_t *sngisdn_event) break; } break; + case 9: /* Remote switch is in "Incoming call proceeding" state */ + switch (ftdmchan->state) { + case FTDM_CHANNEL_STATE_PROGRESS: + case FTDM_CHANNEL_STATE_PROGRESS_MEDIA: + case FTDM_CHANNEL_STATE_GET_CALLERID: + /* Do nothing */ + break; + case FTDM_CHANNEL_STATE_UP: + /* Remote switch missed our CONNECT message, re-send */ + ftdm_sched_timer(((sngisdn_span_data_t*)ftdmchan->span->signal_data)->sched, "delayed_connect", 1, sngisdn_delayed_connect, (void*) sngisdn_info, NULL); + break; + default: + ftdm_log_chan(ftdmchan, FTDM_LOG_CRIT, "Don't know how to handle incompatible state. remote call state:%d our state:%s\n", call_state, ftdm_channel_state2str(ftdmchan->state)); + break; + } + break; case 10: /* Remote switch is in active state */ switch (ftdmchan->state) { case FTDM_CHANNEL_STATE_UP: @@ -899,17 +922,6 @@ void sngisdn_process_sta_cfm (sngisdn_event_data_t *sngisdn_event) break; } break; - case 9: - switch (ftdmchan->state) { - case FTDM_CHANNEL_STATE_PROGRESS: - case FTDM_CHANNEL_STATE_PROGRESS_MEDIA: - /* Do nothing */ - break; - default: - ftdm_log_chan(ftdmchan, FTDM_LOG_CRIT, "Don't know how to handle incompatible state. remote call state:%d our state:%s\n", call_state, ftdm_channel_state2str(ftdmchan->state)); - break; - } - break; case 22: switch (ftdmchan->state) { case FTDM_CHANNEL_STATE_UP: From c296179535d66a28fe18b6bae2969447ab447348 Mon Sep 17 00:00:00 2001 From: Moises Silva Date: Tue, 21 Sep 2010 17:08:44 -0400 Subject: [PATCH 07/15] freetdm: make config and module directory to be a variable and not a macro --- libs/freetdm/src/ftdm_config.c | 31 +++++++++++++++++++++++++++++-- libs/freetdm/src/ftdm_io.c | 21 --------------------- 2 files changed, 29 insertions(+), 23 deletions(-) diff --git a/libs/freetdm/src/ftdm_config.c b/libs/freetdm/src/ftdm_config.c index f6d9c1ae30..291ca33109 100644 --- a/libs/freetdm/src/ftdm_config.c +++ b/libs/freetdm/src/ftdm_config.c @@ -37,6 +37,13 @@ #include "private/ftdm_core.h" +#ifndef FTDM_MOD_DIR +#define FTDM_MOD_DIR "." +#endif + +static char g_ftdm_config_dir[] = FTDM_CONFIG_DIR; +static char g_ftdm_mod_dir[] = FTDM_MOD_DIR; + int ftdm_config_open_file(ftdm_config_t *cfg, const char *file_path) { FILE *f; @@ -46,7 +53,7 @@ int ftdm_config_open_file(ftdm_config_t *cfg, const char *file_path) if (file_path[0] == '/') { path = file_path; } else { - snprintf(path_buf, sizeof(path_buf), "%s%s%s", FTDM_CONFIG_DIR, FTDM_PATH_SEPARATOR, file_path); + snprintf(path_buf, sizeof(path_buf), "%s%s%s", g_ftdm_config_dir, FTDM_PATH_SEPARATOR, file_path); path = path_buf; } @@ -64,7 +71,7 @@ int ftdm_config_open_file(ftdm_config_t *cfg, const char *file_path) int last = -1; char *var, *val; - snprintf(path_buf, sizeof(path_buf), "%s%sfreetdm.conf", FTDM_CONFIG_DIR, FTDM_PATH_SEPARATOR); + snprintf(path_buf, sizeof(path_buf), "%s%sfreetdm.conf", g_ftdm_config_dir, FTDM_PATH_SEPARATOR); path = path_buf; if ((f = fopen(path, "r")) == 0) { @@ -329,6 +336,26 @@ FT_DECLARE(ftdm_status_t) ftdm_conf_node_destroy(ftdm_conf_node_t *node) return FTDM_SUCCESS; } +FT_DECLARE(char *) ftdm_build_dso_path(const char *name, char *path, ftdm_size_t len) +{ +#ifdef WIN32 + const char *ext = ".dll"; + //const char *EXT = ".DLL"; +#elif defined (MACOSX) || defined (DARWIN) + const char *ext = ".dylib"; + //const char *EXT = ".DYLIB"; +#else + const char *ext = ".so"; + //const char *EXT = ".SO"; +#endif + if (*name == *FTDM_PATH_SEPARATOR) { + snprintf(path, len, "%s%s", name, ext); + } else { + snprintf(path, len, "%s%s%s%s", g_ftdm_mod_dir, FTDM_PATH_SEPARATOR, name, ext); + } + return path; +} + /* For Emacs: * Local Variables: * mode:c diff --git a/libs/freetdm/src/ftdm_io.c b/libs/freetdm/src/ftdm_io.c index 97aa01bca0..bb46e798b2 100644 --- a/libs/freetdm/src/ftdm_io.c +++ b/libs/freetdm/src/ftdm_io.c @@ -4073,27 +4073,6 @@ static ftdm_status_t process_module_config(ftdm_io_interface_t *fio) return FTDM_SUCCESS; } -FT_DECLARE(char *) ftdm_build_dso_path(const char *name, char *path, ftdm_size_t len) -{ -#ifdef WIN32 - const char *ext = ".dll"; - //const char *EXT = ".DLL"; -#define FTDM_MOD_DIR "." //todo -#elif defined (MACOSX) || defined (DARWIN) - const char *ext = ".dylib"; - //const char *EXT = ".DYLIB"; -#else - const char *ext = ".so"; - //const char *EXT = ".SO"; -#endif - if (*name == *FTDM_PATH_SEPARATOR) { - snprintf(path, len, "%s%s", name, ext); - } else { - snprintf(path, len, "%s%s%s%s", FTDM_MOD_DIR, FTDM_PATH_SEPARATOR, name, ext); - } - return path; -} - FT_DECLARE(ftdm_status_t) ftdm_global_add_io_interface(ftdm_io_interface_t *interface1) { ftdm_status_t ret = FTDM_SUCCESS; From 5e60c62e08d055f11adb7a4bc73e08af668ba7f9 Mon Sep 17 00:00:00 2001 From: Moises Silva Date: Tue, 21 Sep 2010 13:56:11 -0400 Subject: [PATCH 08/15] freetdm: set conf and mod directory in runtime --- libs/freetdm/mod_freetdm/mod_freetdm.c | 4 ++++ libs/freetdm/src/ftdm_config.c | 18 ++++++++++++++++-- libs/freetdm/src/include/freetdm.h | 6 ++++++ 3 files changed, 26 insertions(+), 2 deletions(-) diff --git a/libs/freetdm/mod_freetdm/mod_freetdm.c b/libs/freetdm/mod_freetdm/mod_freetdm.c index b4a40f0bad..e5311468e3 100755 --- a/libs/freetdm/mod_freetdm/mod_freetdm.c +++ b/libs/freetdm/mod_freetdm/mod_freetdm.c @@ -4074,6 +4074,10 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_freetdm_load) ftdm_global_set_logger(ftdm_logger); + ftdm_global_set_mod_directory(SWITCH_GLOBAL_dirs.mod_dir); + + ftdm_global_set_config_directory(SWITCH_GLOBAL_dirs.conf_dir); + ftdm_cpu_monitor_disable(); if (ftdm_global_init() != FTDM_SUCCESS) { diff --git a/libs/freetdm/src/ftdm_config.c b/libs/freetdm/src/ftdm_config.c index 291ca33109..1b023e93eb 100644 --- a/libs/freetdm/src/ftdm_config.c +++ b/libs/freetdm/src/ftdm_config.c @@ -41,8 +41,22 @@ #define FTDM_MOD_DIR "." #endif -static char g_ftdm_config_dir[] = FTDM_CONFIG_DIR; -static char g_ftdm_mod_dir[] = FTDM_MOD_DIR; +#define FTDM_MAX_CONF_DIR 512 + +static char g_ftdm_config_dir[FTDM_MAX_CONF_DIR] = FTDM_CONFIG_DIR; +static char g_ftdm_mod_dir[FTDM_MAX_CONF_DIR] = FTDM_MOD_DIR; + +FT_DECLARE(void) ftdm_global_set_mod_directory(const char *path) +{ + snprintf(g_ftdm_mod_dir, sizeof(g_ftdm_mod_dir), "%s", path); + ftdm_log(FTDM_LOG_DEBUG, "New mod directory: %s\n", g_ftdm_mod_dir); +} + +FT_DECLARE(void) ftdm_global_set_config_directory(const char *path) +{ + snprintf(g_ftdm_config_dir, sizeof(g_ftdm_config_dir), "%s", path); + ftdm_log(FTDM_LOG_DEBUG, "New config directory: %s\n", g_ftdm_config_dir); +} int ftdm_config_open_file(ftdm_config_t *cfg, const char *file_path) { diff --git a/libs/freetdm/src/include/freetdm.h b/libs/freetdm/src/include/freetdm.h index 1f50a2ccaa..3b847f821e 100644 --- a/libs/freetdm/src/include/freetdm.h +++ b/libs/freetdm/src/include/freetdm.h @@ -1301,6 +1301,12 @@ FT_DECLARE(void) ftdm_global_set_logger(ftdm_logger_t logger); /*! \brief Set the default logger level */ FT_DECLARE(void) ftdm_global_set_default_logger(int level); +/*! \brief Set the directory to look for modules */ +FT_DECLARE(void) ftdm_global_set_mod_directory(const char *path); + +/*! \brief Set the directory to look for configs */ +FT_DECLARE(void) ftdm_global_set_config_directory(const char *path); + /*! \brief Check if the FTDM library is initialized and running */ FT_DECLARE(ftdm_bool_t) ftdm_running(void); From 4999723687be066188ffe02311e6ca7e7f944e21 Mon Sep 17 00:00:00 2001 From: Moises Silva Date: Tue, 21 Sep 2010 14:26:32 -0400 Subject: [PATCH 09/15] freetdm: fix timer scheduling compilation in isdn stack --- .../ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_stack_hndl.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_stack_hndl.c b/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_stack_hndl.c index 33024d73d0..b7af8e98c5 100644 --- a/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_stack_hndl.c +++ b/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_stack_hndl.c @@ -150,7 +150,7 @@ void sngisdn_process_con_ind (sngisdn_event_data_t *sngisdn_event) /* Launch timer in case we never get a FACILITY msg */ if (signal_data->facility_timeout) { ftdm_sched_timer(signal_data->sched, "facility_timeout", signal_data->facility_timeout, - sngisdn_facility_timeout, (void*) sngisdn_info, sngisdn_info->timers[SNGISDN_TIMER_FACILITY]); + sngisdn_facility_timeout, (void*) sngisdn_info, &sngisdn_info->timers[SNGISDN_TIMER_FACILITY]); } break; } else if (ret_val == 0) { From ed01944c15d93885aed94bd9e4f9cee86d8b4c86 Mon Sep 17 00:00:00 2001 From: Moises Silva Date: Wed, 22 Sep 2010 14:59:06 -0400 Subject: [PATCH 10/15] freetdm: add initial changes for FreeTDM channel history feature --- libs/freetdm/mod_freetdm/mod_freetdm.c | 7 ++- libs/freetdm/src/ftdm_io.c | 61 ++++++++++++++++++++ libs/freetdm/src/include/freetdm.h | 8 ++- libs/freetdm/src/include/private/ftdm_core.h | 11 ++++ 4 files changed, 85 insertions(+), 2 deletions(-) diff --git a/libs/freetdm/mod_freetdm/mod_freetdm.c b/libs/freetdm/mod_freetdm/mod_freetdm.c index b4a40f0bad..f87545715a 100755 --- a/libs/freetdm/mod_freetdm/mod_freetdm.c +++ b/libs/freetdm/mod_freetdm/mod_freetdm.c @@ -3660,7 +3660,12 @@ SWITCH_STANDARD_API(ft_function) if(chan_id > ftdm_span_get_chan_count(span)) { stream->write_function(stream, "-ERR invalid channel\n"); } else { + char *dbgstr = NULL; + ftdm_channel_t *fchan = ftdm_span_get_channel(span, chan_id); dump_chan(span, chan_id, stream); + dbgstr = ftdm_channel_get_history_str(fchan); + stream->write_function(stream, "%s\n", dbgstr); + ftdm_free(dbgstr); } } else { stream->write_function(stream, "+OK\n"); @@ -3989,7 +3994,7 @@ SWITCH_STANDARD_API(ft_function) if (rply) { stream->write_function(stream, "%s", rply); - free(rply); + ftdm_free(rply); } else { stream->write_function(stream, "-ERR Usage: %s\n", FT_SYNTAX); } diff --git a/libs/freetdm/src/ftdm_io.c b/libs/freetdm/src/ftdm_io.c index 97aa01bca0..82997185f7 100644 --- a/libs/freetdm/src/ftdm_io.c +++ b/libs/freetdm/src/ftdm_io.c @@ -1293,6 +1293,16 @@ end: ftdm_log_chan_ex(ftdmchan, file, func, line, FTDM_LOG_LEVEL_DEBUG, "Changed state from %s to %s\n", ftdm_channel_state2str(ftdmchan->state), ftdm_channel_state2str(state)); ftdmchan->last_state = ftdmchan->state; ftdmchan->state = state; + ftdmchan->history[ftdmchan->hindex].file = file; + ftdmchan->history[ftdmchan->hindex].func = func; + ftdmchan->history[ftdmchan->hindex].line = line; + ftdmchan->history[ftdmchan->hindex].state = ftdmchan->state; + ftdmchan->history[ftdmchan->hindex].last_state = ftdmchan->last_state; + ftdmchan->history[ftdmchan->hindex].time = ftdm_current_time_in_ms(); + ftdmchan->hindex++; + if (ftdmchan->hindex == ftdm_array_len(ftdmchan->history)) { + ftdmchan->hindex = 0; + } ftdm_set_flag(ftdmchan, FTDM_CHANNEL_STATE_CHANGE); ftdm_mutex_lock(ftdmchan->span->mutex); @@ -5213,6 +5223,57 @@ FT_DECLARE(char *) ftdm_strndup(const char *str, ftdm_size_t inlen) return new; } +#define FTDM_DEBUG_LINE_LEN 255 +FT_DECLARE(char *) ftdm_channel_get_history_str(const ftdm_channel_t *fchan) +{ + uint8_t j = 0; + int written = 0; + char *buff = NULL; + uint8_t i = fchan->hindex; + + int dbglen = ftdm_array_len(fchan->history) * FTDM_DEBUG_LINE_LEN; + int len = dbglen; + + char *debugstr = ftdm_calloc(1, dbglen); + if (!debugstr) { + return NULL; + } + buff = debugstr; + + for (i = fchan->hindex; i < ftdm_array_len(fchan->history); i++) { + if (!fchan->history[i].file) { + break; + } + written = snprintf(buff, len, "%s -> %s at %s %s:%d\n", + ftdm_channel_state2str(fchan->history[i].last_state), ftdm_channel_state2str(fchan->history[i].state), fchan->history[i].func, + fchan->history[i].file, fchan->history[i].line); + if (written >= len) { + ftdm_free(debugstr); + ftdm_log(FTDM_LOG_ERROR, "Not enough memory to build debug history string\n"); + return NULL; + } + len -= written; + buff += written; + } + + for (j = 0; j < fchan->hindex; j++) { + written = snprintf(buff, len, "%s -> %s at %s %s:%d\n", + ftdm_channel_state2str(fchan->history[i].last_state), ftdm_channel_state2str(fchan->history[i].state), fchan->history[i].func, + fchan->history[i].file, fchan->history[i].line); + if (written >= len) { + ftdm_free(debugstr); + ftdm_log(FTDM_LOG_ERROR, "Not enough memory to build debug history string\n"); + return NULL; + } + len -= written; + buff += written; + } + + debugstr[dbglen-1] = 0; + + return debugstr; +} + /* For Emacs: * Local Variables: diff --git a/libs/freetdm/src/include/freetdm.h b/libs/freetdm/src/include/freetdm.h index 1f50a2ccaa..f4a515b476 100644 --- a/libs/freetdm/src/include/freetdm.h +++ b/libs/freetdm/src/include/freetdm.h @@ -1277,7 +1277,13 @@ FT_DECLARE(const char *) ftdm_channel_get_state_str(const ftdm_channel_t *channe /*! \brief For display debugging purposes you can display this string which describes the last channel internal state */ FT_DECLARE(const char *) ftdm_channel_get_last_state_str(const ftdm_channel_t *channel); -/*! \brief For display debugging purposes you can display this string which describes the last channel internal state */ +/*! \brief For display debugging purposes you can display this string which describes the history of the channel + * \param The channel + * \return History string for the channel. You must free the string with ftdm_free + */ +FT_DECLARE(char *) ftdm_channel_get_history_str(const ftdm_channel_t *channel); + +/*! \brief Initialize channel state for an outgoing call */ FT_DECLARE(ftdm_status_t) ftdm_channel_init(ftdm_channel_t *ftdmchan); /*! \brief Initialize the library */ diff --git a/libs/freetdm/src/include/private/ftdm_core.h b/libs/freetdm/src/include/private/ftdm_core.h index a701c1383d..beee868633 100644 --- a/libs/freetdm/src/include/private/ftdm_core.h +++ b/libs/freetdm/src/include/private/ftdm_core.h @@ -356,6 +356,15 @@ typedef struct { } ftdm_dtmf_debug_t; #endif +typedef struct { + const char *file; + const char *func; + int line; + ftdm_channel_state_t state; + ftdm_channel_state_t last_state; + ftdm_time_t time; +} ftdm_channel_history_entry_t; + /* 2^8 table size, one for each byte (sample) value */ #define FTDM_GAINS_TABLE_SIZE 256 struct ftdm_channel { @@ -381,6 +390,8 @@ struct ftdm_channel { ftdm_channel_state_t state; ftdm_channel_state_t last_state; ftdm_channel_state_t init_state; + ftdm_channel_history_entry_t history[10]; + uint8_t hindex; ftdm_mutex_t *mutex; teletone_dtmf_detect_state_t dtmf_detect; uint32_t buffer_delay; From 640b81a27c6cffa927e9fd36bb3c0a9c3b0c4bfe Mon Sep 17 00:00:00 2001 From: Moises Silva Date: Thu, 23 Sep 2010 07:38:58 -0400 Subject: [PATCH 11/15] freetdm: improve state debug dumping --- libs/freetdm/src/ftdm_io.c | 54 +++++++++++++++++++++----------------- 1 file changed, 30 insertions(+), 24 deletions(-) diff --git a/libs/freetdm/src/ftdm_io.c b/libs/freetdm/src/ftdm_io.c index 82997185f7..393f641e68 100644 --- a/libs/freetdm/src/ftdm_io.c +++ b/libs/freetdm/src/ftdm_io.c @@ -5224,49 +5224,55 @@ FT_DECLARE(char *) ftdm_strndup(const char *str, ftdm_size_t inlen) } #define FTDM_DEBUG_LINE_LEN 255 +#define handle_snprintf_result(buff, written, len, debugstr) \ + if (written >= len) { \ + ftdm_free(debugstr); \ + return NULL; \ + } \ + len -= written; \ + buff += written; + FT_DECLARE(char *) ftdm_channel_get_history_str(const ftdm_channel_t *fchan) { - uint8_t j = 0; + char func[255]; + char line[255]; + char states[255]; int written = 0; char *buff = NULL; - uint8_t i = fchan->hindex; - + uint8_t i = 0; int dbglen = ftdm_array_len(fchan->history) * FTDM_DEBUG_LINE_LEN; int len = dbglen; + if (!fchan->history[0].file) { + return ftdm_strdup("-- No state history --\n"); + } + char *debugstr = ftdm_calloc(1, dbglen); if (!debugstr) { return NULL; } buff = debugstr; + written = snprintf(buff, len, "%-30.30s %-30.30s %s", "-- States --", "-- Function --", "-- Location --\n"); + handle_snprintf_result(buff, written, len, debugstr); + for (i = fchan->hindex; i < ftdm_array_len(fchan->history); i++) { if (!fchan->history[i].file) { break; } - written = snprintf(buff, len, "%s -> %s at %s %s:%d\n", - ftdm_channel_state2str(fchan->history[i].last_state), ftdm_channel_state2str(fchan->history[i].state), fchan->history[i].func, - fchan->history[i].file, fchan->history[i].line); - if (written >= len) { - ftdm_free(debugstr); - ftdm_log(FTDM_LOG_ERROR, "Not enough memory to build debug history string\n"); - return NULL; - } - len -= written; - buff += written; + snprintf(states, sizeof(states), "%-5.15s => %-5.15s", ftdm_channel_state2str(fchan->history[i].last_state), ftdm_channel_state2str(fchan->history[i].state)); + snprintf(func, sizeof(func), "[%s]", fchan->history[i].func); + snprintf(line, sizeof(func), "[%s:%d]", fchan->history[i].file, fchan->history[i].line); + written = snprintf(buff, len, "%-30.30s %-30.30s %s\n", states, func, line); + handle_snprintf_result(buff, written, len, debugstr); } - for (j = 0; j < fchan->hindex; j++) { - written = snprintf(buff, len, "%s -> %s at %s %s:%d\n", - ftdm_channel_state2str(fchan->history[i].last_state), ftdm_channel_state2str(fchan->history[i].state), fchan->history[i].func, - fchan->history[i].file, fchan->history[i].line); - if (written >= len) { - ftdm_free(debugstr); - ftdm_log(FTDM_LOG_ERROR, "Not enough memory to build debug history string\n"); - return NULL; - } - len -= written; - buff += written; + for (i = 0; i < fchan->hindex; i++) { + snprintf(states, sizeof(states), "%-5.15s => %-5.15s", ftdm_channel_state2str(fchan->history[i].last_state), ftdm_channel_state2str(fchan->history[i].state)); + snprintf(func, sizeof(func), "[%s]", fchan->history[i].func); + snprintf(line, sizeof(func), "[%s:%d]", fchan->history[i].file, fchan->history[i].line); + written = snprintf(buff, len, "%-30.30s %-30.30s %s\n", states, func, line); + handle_snprintf_result(buff, written, len, debugstr); } debugstr[dbglen-1] = 0; From d9fece6c0e325ee0a5394807395f2b2e2bf68f20 Mon Sep 17 00:00:00 2001 From: Konrad Hammel Date: Thu, 23 Sep 2010 10:09:38 -0400 Subject: [PATCH 12/15] freetdm: ss7 - update to timers to match changes in core timers --- .../ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_main.c | 12 ++++++------ .../ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_main.h | 2 +- .../ftmod_sangoma_ss7/ftmod_sangoma_ss7_timers.c | 2 +- 3 files changed, 8 insertions(+), 8 deletions(-) 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 19f042bc2e..3ef8db53d1 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 @@ -493,7 +493,7 @@ static void ftdm_sangoma_ss7_process_state_change (ftdm_channel_t * ftdmchan) /*now go to the RING state */ ftdm_set_state_locked (ftdmchan, FTDM_CHANNEL_STATE_RING); - } else if (i > g_ftdm_sngss7_data.min_digits) { + } else if (i >= g_ftdm_sngss7_data.min_digits) { SS7_DEBUG_CHAN(ftdmchan, "Received %d digits (min digits = %d)\n", i, g_ftdm_sngss7_data.min_digits); /*now go to the RING state */ @@ -511,7 +511,7 @@ static void ftdm_sangoma_ss7_process_state_change (ftdm_channel_t * ftdmchan) sngss7_info->t35.beat, sngss7_info->t35.callback, &sngss7_info->t35, - &sngss7_info->t35.heartbeat_timer)) { + &sngss7_info->t35.hb_timer_id)) { SS7_ERROR ("Unable to schedule timer, hanging up call!\n"); @@ -536,8 +536,8 @@ static void ftdm_sangoma_ss7_process_state_change (ftdm_channel_t * ftdmchan) } /* kill t35 if active */ - if (sngss7_info->t35.heartbeat_timer) { - ftdm_sched_cancel_timer (sngss7_info->t35.sched,&sngss7_info->t35.heartbeat_timer); + if (sngss7_info->t35.hb_timer_id) { + ftdm_sched_cancel_timer (sngss7_info->t35.sched, sngss7_info->t35.hb_timer_id); } SS7_DEBUG_CHAN(ftdmchan, "Sending incoming call from %s to %s to FTDM core\n", @@ -816,8 +816,8 @@ static void ftdm_sangoma_ss7_process_state_change (ftdm_channel_t * ftdmchan) } /* if ((ftdmchan->last_state == FTDM_CHANNEL_STATE_RESTART) */ /* check if t35 is active */ - if (sngss7_info->t35.heartbeat_timer) { - ftdm_sched_cancel_timer (sngss7_info->t35.sched, &sngss7_info->t35.heartbeat_timer); + if (sngss7_info->t35.hb_timer_id) { + ftdm_sched_cancel_timer (sngss7_info->t35.sched, sngss7_info->t35.hb_timer_id); } /* clear all of the call specific data store in the channel structure */ 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 415a897181..850bbf0d1a 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 @@ -316,7 +316,7 @@ typedef struct ftdm_sngss7_data { }ftdm_sngss7_data_t; typedef struct sngss7_timer_data { - ftdm_timer_t *heartbeat_timer; + ftdm_timer_id_t hb_timer_id; int beat; int counter; ftdm_sched_callback_t callback; diff --git a/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_timers.c b/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_timers.c index 5185ffcc62..75b32d6892 100644 --- a/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_timers.c +++ b/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_timers.c @@ -64,7 +64,7 @@ void handle_isup_t35(void *userdata) sngss7_set_flag(sngss7_info, FLAG_LOCAL_REL); /* hang up on timer expiry */ - ftdmchan->caller_data.hangup_cause = 102; + ftdmchan->caller_data.hangup_cause = 28; /* end the call */ ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_CANCEL); From f37729152d625e24c4a6303be2bad8a8245765c2 Mon Sep 17 00:00:00 2001 From: Moises Silva Date: Thu, 23 Sep 2010 09:30:08 -0400 Subject: [PATCH 13/15] freetdm: dump uuid of the channel associated session if any --- libs/freetdm/mod_freetdm/mod_freetdm.c | 20 ++++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) diff --git a/libs/freetdm/mod_freetdm/mod_freetdm.c b/libs/freetdm/mod_freetdm/mod_freetdm.c index 8ec44ef60c..086cc4ae2e 100755 --- a/libs/freetdm/mod_freetdm/mod_freetdm.c +++ b/libs/freetdm/mod_freetdm/mod_freetdm.c @@ -3451,7 +3451,10 @@ void dump_chan(ftdm_span_t *span, uint32_t chan_id, switch_stream_handle_t *stre const char *chan_type; const char *state; const char *last_state; + const char *uuid = NULL; + char sessionid[255]; float txgain, rxgain; + switch_core_session_t *session = NULL; ftdm_alarm_flag_t alarmflag; ftdm_caller_data_t *caller_data; ftdm_channel_t *ftdmchan; @@ -3461,6 +3464,7 @@ void dump_chan(ftdm_span_t *span, uint32_t chan_id, switch_stream_handle_t *stre return; } + strcpy(sessionid, "(none)"); ftdmchan = ftdm_span_get_channel(span, chan_id); span_id = ftdm_span_get_id(span); @@ -3475,6 +3479,16 @@ void dump_chan(ftdm_span_t *span, uint32_t chan_id, switch_stream_handle_t *stre ftdm_channel_get_sig_status(ftdmchan, &sigstatus); ftdm_channel_get_alarms(ftdmchan, &alarmflag); + uuid = ftdm_channel_get_uuid(ftdmchan, 0); + if (!zstr(uuid)) { + if (!(session = switch_core_session_locate(uuid))) { + snprintf(sessionid, sizeof(sessionid), "%s (dead)", uuid); + } else { + snprintf(sessionid, sizeof(sessionid), "%s", uuid); + switch_core_session_rwunlock(session); + } + } + stream->write_function(stream, "span_id: %u\n" "chan_id: %u\n" @@ -3494,7 +3508,8 @@ void dump_chan(ftdm_span_t *span, uint32_t chan_id, switch_stream_handle_t *stre "aniII: %s\n" "dnis: %s\n" "rdnis: %s\n" - "cause: %s\n\n", + "cause: %s\n" + "session: %s\n\n", span_id, chan_id, phspan_id, @@ -3513,7 +3528,8 @@ void dump_chan(ftdm_span_t *span, uint32_t chan_id, switch_stream_handle_t *stre caller_data->aniII, caller_data->dnis.digits, caller_data->rdnis.digits, - switch_channel_cause2str(caller_data->hangup_cause)); + switch_channel_cause2str(caller_data->hangup_cause), + sessionid); } void dump_chan_xml(ftdm_span_t *span, uint32_t chan_id, switch_stream_handle_t *stream) From 1c9fe263d67c0828615857e4dfd8c40dad61f295 Mon Sep 17 00:00:00 2001 From: David Yat Sin Date: Thu, 23 Sep 2010 13:58:20 -0400 Subject: [PATCH 14/15] Changed ftdm_cpu_monitor behaviour --- libs/freetdm/mod_freetdm/mod_freetdm.c | 2 -- libs/freetdm/src/ftdm_io.c | 28 +++++++++++-------- .../ftmod_sangoma_isdn_stack_cfg.c | 3 +- 3 files changed, 19 insertions(+), 14 deletions(-) diff --git a/libs/freetdm/mod_freetdm/mod_freetdm.c b/libs/freetdm/mod_freetdm/mod_freetdm.c index 086cc4ae2e..3ad4393ab5 100755 --- a/libs/freetdm/mod_freetdm/mod_freetdm.c +++ b/libs/freetdm/mod_freetdm/mod_freetdm.c @@ -4099,8 +4099,6 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_freetdm_load) ftdm_global_set_config_directory(SWITCH_GLOBAL_dirs.conf_dir); - ftdm_cpu_monitor_disable(); - if (ftdm_global_init() != FTDM_SUCCESS) { ftdm_log(FTDM_LOG_ERROR, "Error loading FreeTDM\n"); return SWITCH_STATUS_TERM; diff --git a/libs/freetdm/src/ftdm_io.c b/libs/freetdm/src/ftdm_io.c index 0cb217065a..18ae87c540 100644 --- a/libs/freetdm/src/ftdm_io.c +++ b/libs/freetdm/src/ftdm_io.c @@ -86,6 +86,7 @@ FT_DECLARE(ftdm_time_t) ftdm_current_time_in_ms(void) } typedef struct { + uint8_t enabled; uint8_t running; uint8_t alarm; uint32_t interval; @@ -112,8 +113,6 @@ static struct { cpu_monitor_t cpu_monitor; } globals; -static uint8_t ftdm_cpu_monitor_disabled = 0; - enum ftdm_enum_cpu_alarm_action_flags { FTDM_CPU_ALARM_ACTION_WARN = (1 << 0), @@ -4004,7 +4003,14 @@ static ftdm_status_t load_config(void) ftdm_log(FTDM_LOG_ERROR, "unknown span variable '%s'\n", var); } } else if (!strncasecmp(cfg.category, "general", 7)) { - if (!strncasecmp(var, "cpu_monitoring_interval", sizeof("cpu_monitoring_interval")-1)) { + if (!strncasecmp(var, "cpu_monitor", sizeof("cpu_monitor")-1)) { + if (!strncasecmp(val, "yes", 3)) { + globals.cpu_monitor.enabled = 1; + if (!globals.cpu_monitor.alarm_action_flags) { + globals.cpu_monitor.alarm_action_flags |= FTDM_CPU_ALARM_ACTION_WARN; + } + } + } else if (!strncasecmp(var, "cpu_monitoring_interval", sizeof("cpu_monitoring_interval")-1)) { if (atoi(val) > 0) { globals.cpu_monitor.interval = atoi(val); } else { @@ -4749,12 +4755,6 @@ static void ftdm_cpu_monitor_stop(void) ftdm_interrupt_destroy(&globals.cpu_monitor.interrupt); } -FT_DECLARE(void) ftdm_cpu_monitor_disable(void) -{ - ftdm_cpu_monitor_disabled = 1; -} - - FT_DECLARE(ftdm_status_t) ftdm_global_init(void) { memset(&globals, 0, sizeof(globals)); @@ -4796,8 +4796,9 @@ FT_DECLARE(ftdm_status_t) ftdm_global_configuration(void) ftdm_log(FTDM_LOG_NOTICE, "Modules configured: %d \n", modcount); + globals.cpu_monitor.enabled = 0; globals.cpu_monitor.interval = 1000; - globals.cpu_monitor.alarm_action_flags = FTDM_CPU_ALARM_ACTION_WARN | FTDM_CPU_ALARM_ACTION_REJECT; + globals.cpu_monitor.alarm_action_flags = 0; globals.cpu_monitor.set_alarm_threshold = 80; globals.cpu_monitor.reset_alarm_threshold = 70; @@ -4807,7 +4808,12 @@ FT_DECLARE(ftdm_status_t) ftdm_global_configuration(void) return FTDM_FAIL; } - if (!ftdm_cpu_monitor_disabled) { + if (globals.cpu_monitor.enabled) { + ftdm_log(FTDM_LOG_INFO, "CPU Monitor is running interval:%d lo-thres:%d hi-thres:%d\n", + globals.cpu_monitor.interval, + globals.cpu_monitor.set_alarm_threshold, + globals.cpu_monitor.reset_alarm_threshold); + if (ftdm_cpu_monitor_start() != FTDM_SUCCESS) { return FTDM_FAIL; } diff --git a/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_stack_cfg.c b/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_stack_cfg.c index 942c2e4531..3a4a001089 100644 --- a/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_stack_cfg.c +++ b/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_stack_cfg.c @@ -608,9 +608,10 @@ ftdm_status_t sng_isdn_stack_cfg_q931_dlsap(ftdm_span_t *span) cfg.hdr.entId.ent = ENTIN; cfg.hdr.entId.inst = S_INST; cfg.hdr.elmId.elmnt = STDLSAP; - + cfg.hdr.response.selector=0; + cfg.t.cfg.s.inDLSAP.sapId = signal_data->link_id; cfg.t.cfg.s.inDLSAP.spId = signal_data->link_id; cfg.t.cfg.s.inDLSAP.swtch = sng_isdn_stack_switchtype(signal_data->switchtype); From 562ac0efe3ef5bf955edb0399913a1c1cdf3db18 Mon Sep 17 00:00:00 2001 From: Moises Silva Date: Fri, 24 Sep 2010 08:35:20 -0400 Subject: [PATCH 15/15] freetdm: use ftdm stream instead of funky string concatenation with snprintf add ftdm core state filtering for debugging --- libs/freetdm/src/ftdm_io.c | 137 +++++++++++++++++++++++++++++-------- 1 file changed, 108 insertions(+), 29 deletions(-) diff --git a/libs/freetdm/src/ftdm_io.c b/libs/freetdm/src/ftdm_io.c index 0cb217065a..48dbe262fd 100644 --- a/libs/freetdm/src/ftdm_io.c +++ b/libs/freetdm/src/ftdm_io.c @@ -3689,6 +3689,102 @@ static struct { ftdm_io_interface_t *pika_interface; } interfaces; +static void print_channels_by_state(ftdm_stream_handle_t *stream, ftdm_channel_state_t state, int not, int *count) +{ + ftdm_hash_iterator_t *i = NULL; + ftdm_span_t *span; + ftdm_channel_t *fchan = NULL; + ftdm_iterator_t *citer = NULL; + ftdm_iterator_t *curr = NULL; + const void *key = NULL; + void *val = NULL; + + *count = 0; + + ftdm_mutex_lock(globals.mutex); + + for (i = hashtable_first(globals.span_hash); i; i = hashtable_next(i)) { + hashtable_this(i, &key, NULL, &val); + if (!key || !val) { + break; + } + span = val; + citer = ftdm_span_get_chan_iterator(span, NULL); + if (!citer) { + continue; + } + for (curr = citer ; curr; curr = ftdm_iterator_next(curr)) { + fchan = ftdm_iterator_current(curr); + if (not && (fchan->state != state)) { + stream->write_function(stream, "[s%dc%d][%d:%d] in state %s\n", + fchan->span_id, fchan->chan_id, + fchan->physical_span_id, fchan->physical_chan_id, ftdm_channel_state2str(fchan->state)); + (*count)++; + } else if (!not && (fchan->state == state)) { + stream->write_function(stream, "[s%dc%d][%d:%d] in state %s\n", + fchan->span_id, fchan->chan_id, + fchan->physical_span_id, fchan->physical_chan_id, ftdm_channel_state2str(fchan->state)); + (*count)++; + } + } + ftdm_iterator_free(citer); + } + + ftdm_mutex_unlock(globals.mutex); +} + +static char *handle_core_command(const char *cmd) +{ + char *mycmd = NULL; + int argc = 0; + int count = 0; + int not = 0; + char *argv[10] = { 0 }; + char *state = NULL; + ftdm_channel_state_t i = FTDM_CHANNEL_STATE_INVALID; + ftdm_stream_handle_t stream = { 0 }; + + FTDM_STANDARD_STREAM(stream); + + if (cmd) { + mycmd = ftdm_strdup(cmd); + argc = ftdm_separate_string(mycmd, ' ', argv, (sizeof(argv) / sizeof(argv[0]))); + } else { + stream.write_function(&stream, "invalid core command\n"); + goto done; + } + + if (!strcasecmp(argv[0], "state")) { + if (argc < 2) { + stream.write_function(&stream, "core state command requires an argument\n"); + goto done; + } + state = argv[1]; + if (argv[1][0] == '!') { + not = 1; + state++; + } + for (i = FTDM_CHANNEL_STATE_DOWN; i < FTDM_CHANNEL_STATE_INVALID; i++) { + if (!strcasecmp(state, ftdm_channel_state2str(i))) { + break; + } + } + if (i == FTDM_CHANNEL_STATE_INVALID) { + stream.write_function(&stream, "invalid state %s\n", state); + goto done; + } + print_channels_by_state(&stream, i, not, &count); + stream.write_function(&stream, "\nTotal channels %s %s: %d\n", not ? "not in state" : "in state", ftdm_channel_state2str(i), count); + } else { + stream.write_function(&stream, "invalid core command %s\n", argv[0]); + } + +done: + ftdm_safe_free(mycmd); + + return stream.data; +} + FT_DECLARE(char *) ftdm_api_execute(const char *cmd) { ftdm_io_interface_t *fio = NULL; @@ -3703,6 +3799,10 @@ FT_DECLARE(char *) ftdm_api_execute(const char *cmd) } type = dup; + + if (!strcasecmp(type, "core")) { + return handle_core_command(cmd); + } ftdm_mutex_lock(globals.mutex); if (!(fio = (ftdm_io_interface_t *) hashtable_search(globals.interface_hash, (void *)type))) { @@ -5202,38 +5302,21 @@ FT_DECLARE(char *) ftdm_strndup(const char *str, ftdm_size_t inlen) return new; } -#define FTDM_DEBUG_LINE_LEN 255 -#define handle_snprintf_result(buff, written, len, debugstr) \ - if (written >= len) { \ - ftdm_free(debugstr); \ - return NULL; \ - } \ - len -= written; \ - buff += written; - FT_DECLARE(char *) ftdm_channel_get_history_str(const ftdm_channel_t *fchan) { char func[255]; char line[255]; char states[255]; - int written = 0; - char *buff = NULL; uint8_t i = 0; - int dbglen = ftdm_array_len(fchan->history) * FTDM_DEBUG_LINE_LEN; - int len = dbglen; + ftdm_stream_handle_t stream = { 0 }; + FTDM_STANDARD_STREAM(stream); if (!fchan->history[0].file) { - return ftdm_strdup("-- No state history --\n"); + stream.write_function(&stream, "-- No state history --\n"); + return stream.data; } - char *debugstr = ftdm_calloc(1, dbglen); - if (!debugstr) { - return NULL; - } - buff = debugstr; - - written = snprintf(buff, len, "%-30.30s %-30.30s %s", "-- States --", "-- Function --", "-- Location --\n"); - handle_snprintf_result(buff, written, len, debugstr); + stream.write_function(&stream, "%-30.30s %-30.30s %s", "-- States --", "-- Function --", "-- Location --\n"); for (i = fchan->hindex; i < ftdm_array_len(fchan->history); i++) { if (!fchan->history[i].file) { @@ -5242,21 +5325,17 @@ FT_DECLARE(char *) ftdm_channel_get_history_str(const ftdm_channel_t *fchan) snprintf(states, sizeof(states), "%-5.15s => %-5.15s", ftdm_channel_state2str(fchan->history[i].last_state), ftdm_channel_state2str(fchan->history[i].state)); snprintf(func, sizeof(func), "[%s]", fchan->history[i].func); snprintf(line, sizeof(func), "[%s:%d]", fchan->history[i].file, fchan->history[i].line); - written = snprintf(buff, len, "%-30.30s %-30.30s %s\n", states, func, line); - handle_snprintf_result(buff, written, len, debugstr); + stream.write_function(&stream, "%-30.30s %-30.30s %s\n", states, func, line); } for (i = 0; i < fchan->hindex; i++) { snprintf(states, sizeof(states), "%-5.15s => %-5.15s", ftdm_channel_state2str(fchan->history[i].last_state), ftdm_channel_state2str(fchan->history[i].state)); snprintf(func, sizeof(func), "[%s]", fchan->history[i].func); snprintf(line, sizeof(func), "[%s:%d]", fchan->history[i].file, fchan->history[i].line); - written = snprintf(buff, len, "%-30.30s %-30.30s %s\n", states, func, line); - handle_snprintf_result(buff, written, len, debugstr); + stream.write_function(&stream, "%-30.30s %-30.30s %s\n", states, func, line); } - debugstr[dbglen-1] = 0; - - return debugstr; + return stream.data; }