svn-style merge from moy.ss7grs_perchan branch (spin off releases.3.2)

addressed issue with multiple GRS at the same time in a single span
revisions merged: afcc831d6fa1fccaf7ef091b8c48b905a76d834d 9c815c9ecd7102e7d30c3988cd41682b8cbade0b
This commit is contained in:
Moises Silva 2011-07-28 08:04:07 -04:00
parent 372ae224e5
commit ea16afe34e
10 changed files with 684 additions and 480 deletions

View File

@ -5433,12 +5433,14 @@ static void execute_safety_hangup(void *data)
FT_DECLARE(ftdm_status_t) ftdm_span_send_signal(ftdm_span_t *span, ftdm_sigmsg_t *sigmsg)
{
ftdm_channel_t *fchan = NULL;
if (sigmsg->channel) {
ftdm_mutex_lock(sigmsg->channel->mutex);
sigmsg->chan_id = sigmsg->channel->chan_id;
sigmsg->span_id = sigmsg->channel->span_id;
sigmsg->call_id = sigmsg->channel->caller_data.call_id;
sigmsg->call_priv = sigmsg->channel->caller_data.priv;
fchan = sigmsg->channel;
ftdm_channel_lock(fchan);
sigmsg->chan_id = fchan->chan_id;
sigmsg->span_id = fchan->span_id;
sigmsg->call_id = fchan->caller_data.call_id;
sigmsg->call_priv = fchan->caller_data.priv;
}
/* some core things to do on special events */
@ -5447,14 +5449,14 @@ FT_DECLARE(ftdm_status_t) ftdm_span_send_signal(ftdm_span_t *span, ftdm_sigmsg_t
case FTDM_SIGEVENT_SIGSTATUS_CHANGED:
{
if (sigmsg->ev_data.sigstatus.status == FTDM_SIG_STATE_UP) {
ftdm_set_flag(sigmsg->channel, FTDM_CHANNEL_SIG_UP);
ftdm_clear_flag(sigmsg->channel, FTDM_CHANNEL_SUSPENDED);
ftdm_set_flag(fchan, FTDM_CHANNEL_SIG_UP);
ftdm_clear_flag(fchan, FTDM_CHANNEL_SUSPENDED);
} else {
ftdm_clear_flag(sigmsg->channel, FTDM_CHANNEL_SIG_UP);
ftdm_clear_flag(fchan, FTDM_CHANNEL_SIG_UP);
if (sigmsg->ev_data.sigstatus.status == FTDM_SIG_STATE_SUSPENDED) {
ftdm_set_flag(sigmsg->channel, FTDM_CHANNEL_SUSPENDED);
ftdm_set_flag(fchan, FTDM_CHANNEL_SUSPENDED);
} else {
ftdm_clear_flag(sigmsg->channel, FTDM_CHANNEL_SUSPENDED);
ftdm_clear_flag(fchan, FTDM_CHANNEL_SUSPENDED);
}
}
}
@ -5462,14 +5464,14 @@ FT_DECLARE(ftdm_status_t) ftdm_span_send_signal(ftdm_span_t *span, ftdm_sigmsg_t
case FTDM_SIGEVENT_START:
{
ftdm_assert(!ftdm_test_flag(sigmsg->channel, FTDM_CHANNEL_CALL_STARTED), "Started call twice!");
ftdm_assert(!ftdm_test_flag(fchan, FTDM_CHANNEL_CALL_STARTED), "Started call twice!");
if (ftdm_test_flag(sigmsg->channel, FTDM_CHANNEL_OUTBOUND)) {
ftdm_log_chan_msg(sigmsg->channel, FTDM_LOG_WARNING, "Inbound call taking over outbound channel\n");
ftdm_clear_flag(sigmsg->channel, FTDM_CHANNEL_OUTBOUND);
if (ftdm_test_flag(fchan, FTDM_CHANNEL_OUTBOUND)) {
ftdm_log_chan_msg(fchan, FTDM_LOG_WARNING, "Inbound call taking over outbound channel\n");
ftdm_clear_flag(fchan, FTDM_CHANNEL_OUTBOUND);
}
ftdm_set_flag(sigmsg->channel, FTDM_CHANNEL_CALL_STARTED);
ftdm_call_set_call_id(sigmsg->channel, &sigmsg->channel->caller_data);
ftdm_set_flag(fchan, FTDM_CHANNEL_CALL_STARTED);
ftdm_call_set_call_id(fchan, &fchan->caller_data);
/* when cleaning up the public API I added this because mod_freetdm.c on_fxs_signal was
* doing it during SIGEVENT_START, but now that flags are private they can't, wonder if
* is needed at all? */
@ -5483,8 +5485,8 @@ FT_DECLARE(ftdm_status_t) ftdm_span_send_signal(ftdm_span_t *span, ftdm_sigmsg_t
case FTDM_SIGEVENT_PROGRESS_MEDIA:
{
/* test signaling module compliance */
if (sigmsg->channel->state != FTDM_CHANNEL_STATE_PROGRESS_MEDIA) {
ftdm_log_chan(sigmsg->channel, FTDM_LOG_WARNING, "FTDM_SIGEVENT_PROGRESS_MEDIA sent in state %s\n", ftdm_channel_state2str(sigmsg->channel->state));
if (fchan->state != FTDM_CHANNEL_STATE_PROGRESS_MEDIA) {
ftdm_log_chan(fchan, FTDM_LOG_WARNING, "FTDM_SIGEVENT_PROGRESS_MEDIA sent in state %s\n", ftdm_channel_state2str(fchan->state));
}
}
break;
@ -5492,8 +5494,8 @@ FT_DECLARE(ftdm_status_t) ftdm_span_send_signal(ftdm_span_t *span, ftdm_sigmsg_t
case FTDM_SIGEVENT_UP:
{
/* test signaling module compliance */
if (sigmsg->channel->state != FTDM_CHANNEL_STATE_UP) {
ftdm_log_chan(sigmsg->channel, FTDM_LOG_WARNING, "FTDM_SIGEVENT_UP sent in state %s\n", ftdm_channel_state2str(sigmsg->channel->state));
if (fchan->state != FTDM_CHANNEL_STATE_UP) {
ftdm_log_chan(fchan, FTDM_LOG_WARNING, "FTDM_SIGEVENT_UP sent in state %s\n", ftdm_channel_state2str(fchan->state));
}
}
break;
@ -5505,20 +5507,20 @@ FT_DECLARE(ftdm_status_t) ftdm_span_send_signal(ftdm_span_t *span, ftdm_sigmsg_t
/* if the call was never started, do not send SIGEVENT_STOP
this happens for FXS devices in ftmod_analog which blindly send SIGEVENT_STOP, we should fix it there ... */
if (!ftdm_test_flag(sigmsg->channel, FTDM_CHANNEL_CALL_STARTED)) {
ftdm_log_chan_msg(sigmsg->channel, FTDM_LOG_DEBUG, "Ignoring SIGEVENT_STOP since user never knew about a call in this channel\n");
if (!ftdm_test_flag(fchan, FTDM_CHANNEL_CALL_STARTED)) {
ftdm_log_chan_msg(fchan, FTDM_LOG_DEBUG, "Ignoring SIGEVENT_STOP since user never knew about a call in this channel\n");
goto done;
}
if (ftdm_test_flag(sigmsg->channel, FTDM_CHANNEL_USER_HANGUP)) {
ftdm_log_chan_msg(sigmsg->channel, FTDM_LOG_DEBUG, "Ignoring SIGEVENT_STOP since user already requested hangup\n");
if (ftdm_test_flag(fchan, FTDM_CHANNEL_USER_HANGUP)) {
ftdm_log_chan_msg(fchan, 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 (fchan->state == FTDM_CHANNEL_STATE_TERMINATING) {
ftdm_log_chan_msg(fchan, 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", FORCE_HANGUP_TIMER, execute_safety_hangup, sigmsg->channel, &sigmsg->channel->hangup_timer);
ftdm_sched_timer(globals.timingsched, "safety-hangup", FORCE_HANGUP_TIMER, execute_safety_hangup, fchan, &fchan->hangup_timer);
}
}
break;
@ -5537,8 +5539,8 @@ FT_DECLARE(ftdm_status_t) ftdm_span_send_signal(ftdm_span_t *span, ftdm_sigmsg_t
done:
if (sigmsg->channel) {
ftdm_mutex_unlock(sigmsg->channel->mutex);
if (fchan) {
ftdm_channel_unlock(fchan);
}
return FTDM_SUCCESS;

View File

@ -27,6 +27,7 @@
# endif
# include <windows.h>
#endif
/*#define FTDM_DEBUG_MUTEX 0*/
#include "private/ftdm_core.h"
#include "ftdm_threadmutex.h"
@ -46,8 +47,26 @@ struct ftdm_mutex {
#define FTDM_THREAD_CALLING_CONVENTION
#ifdef FTDM_DEBUG_MUTEX
#define FTDM_MUTEX_MAX_REENTRANCY 30
typedef struct ftdm_lock_entry {
const char *file;
const char *func;
uint32_t line;
} ftdm_lock_entry_t;
typedef struct ftdm_lock_history {
ftdm_lock_entry_t locked;
ftdm_lock_entry_t unlocked;
} ftdm_lock_history_t;
#endif
struct ftdm_mutex {
pthread_mutex_t mutex;
#ifdef FTDM_DEBUG_MUTEX
ftdm_lock_history_t lock_history[FTDM_MUTEX_MAX_REENTRANCY];
uint8_t reentrancy;
#endif
};
#endif
@ -112,7 +131,7 @@ FT_DECLARE(ftdm_status_t) ftdm_thread_create_detached_ex(ftdm_thread_function_t
ftdm_thread_t *thread = NULL;
ftdm_status_t status = FTDM_FAIL;
if (!func || !(thread = (ftdm_thread_t *)ftdm_malloc(sizeof(ftdm_thread_t)))) {
if (!func || !(thread = (ftdm_thread_t *)ftdm_calloc(1, sizeof(ftdm_thread_t)))) {
goto done;
}
@ -162,7 +181,7 @@ FT_DECLARE(ftdm_status_t) ftdm_mutex_create(ftdm_mutex_t **mutex)
#endif
ftdm_mutex_t *check = NULL;
check = (ftdm_mutex_t *)ftdm_malloc(sizeof(**mutex));
check = (ftdm_mutex_t *)ftdm_calloc(1, sizeof(**mutex));
if (!check)
goto done;
#ifdef WIN32
@ -209,21 +228,40 @@ FT_DECLARE(ftdm_status_t) ftdm_mutex_destroy(ftdm_mutex_t **mutex)
return FTDM_SUCCESS;
}
FT_DECLARE(ftdm_status_t) _ftdm_mutex_lock(ftdm_mutex_t *mutex)
#define ADD_LOCK_HISTORY(mutex, file, line, func) \
{ \
if ((mutex)->reentrancy < FTDM_MUTEX_MAX_REENTRANCY) { \
(mutex)->lock_history[mutex->reentrancy].locked.file = (file); \
(mutex)->lock_history[mutex->reentrancy].locked.func = (func); \
(mutex)->lock_history[mutex->reentrancy].locked.line = (line); \
(mutex)->lock_history[mutex->reentrancy].unlocked.file = NULL; \
(mutex)->lock_history[mutex->reentrancy].unlocked.func = NULL; \
(mutex)->lock_history[mutex->reentrancy].unlocked.line = 0; \
(mutex)->reentrancy++; \
if ((mutex)->reentrancy == FTDM_MUTEX_MAX_REENTRANCY) { \
ftdm_log((file), (func), (line), FTDM_LOG_LEVEL_ERROR, "Max reentrancy reached for mutex %p\n", (mutex)); \
} \
} \
}
FT_DECLARE(ftdm_status_t) _ftdm_mutex_lock(const char *file, int line, const char *func, ftdm_mutex_t *mutex)
{
#ifdef WIN32
EnterCriticalSection(&mutex->mutex);
#else
int err;
if ((err = pthread_mutex_lock(&mutex->mutex))) {
ftdm_log(FTDM_LOG_ERROR, "Failed to lock mutex %d:%s\n", err, strerror(err));
ftdm_log(file, func, line, FTDM_LOG_LEVEL_ERROR, "Failed to lock mutex %d:%s\n", err, strerror(err));
return FTDM_FAIL;
}
#endif
#ifdef FTDM_DEBUG_MUTEX
ADD_LOCK_HISTORY(mutex, file, line, func);
#endif
return FTDM_SUCCESS;
}
FT_DECLARE(ftdm_status_t) _ftdm_mutex_trylock(ftdm_mutex_t *mutex)
FT_DECLARE(ftdm_status_t) _ftdm_mutex_trylock(const char *file, int line, const char *func, ftdm_mutex_t *mutex)
{
#ifdef WIN32
if (!TryEnterCriticalSection(&mutex->mutex))
@ -231,17 +269,43 @@ FT_DECLARE(ftdm_status_t) _ftdm_mutex_trylock(ftdm_mutex_t *mutex)
#else
if (pthread_mutex_trylock(&mutex->mutex))
return FTDM_FAIL;
#endif
#ifdef FTDM_DEBUG_MUTEX
ADD_LOCK_HISTORY(mutex, file, line, func);
#endif
return FTDM_SUCCESS;
}
FT_DECLARE(ftdm_status_t) _ftdm_mutex_unlock(ftdm_mutex_t *mutex)
FT_DECLARE(ftdm_status_t) _ftdm_mutex_unlock(const char *file, int line, const char *func, ftdm_mutex_t *mutex)
{
#ifdef FTDM_DEBUG_MUTEX
int i = 0;
if (mutex->reentrancy == 0) {
ftdm_log(file, func, line, FTDM_LOG_LEVEL_ERROR, "Cannot unlock something that is not locked!\n");
return FTDM_FAIL;
}
i = mutex->reentrancy - 1;
/* I think this is a fair assumption when debugging */
if (func != mutex->lock_history[i].locked.func) {
ftdm_log(file, func, line, FTDM_LOG_LEVEL_WARNING, "Mutex %p was suspiciously locked at %s->%s:%d but unlocked at %s->%s:%d!\n",
mutex, mutex->lock_history[i].locked.func, mutex->lock_history[i].locked.file, mutex->lock_history[i].locked.line,
func, file, line);
}
mutex->lock_history[i].unlocked.file = file;
mutex->lock_history[i].unlocked.line = line;
mutex->lock_history[i].unlocked.func = func;
mutex->reentrancy--;
#endif
#ifdef WIN32
LeaveCriticalSection(&mutex->mutex);
#else
if (pthread_mutex_unlock(&mutex->mutex))
if (pthread_mutex_unlock(&mutex->mutex)) {
ftdm_log(file, func, line, FTDM_LOG_LEVEL_ERROR, "Failed to unlock mutex: %s\n", strerror(errno));
#ifdef FTDM_DEBUG_MUTEX
mutex->reentrancy++;
#endif
return FTDM_FAIL;
}
#endif
return FTDM_SUCCESS;
}

View File

@ -1618,10 +1618,11 @@ static ftdm_status_t handle_tx_rsc(ftdm_stream_handle_t *stream, int span, int c
/******************************************************************************/
static ftdm_status_t handle_tx_grs(ftdm_stream_handle_t *stream, int span, int chan, int range, int verbose)
{
int x;
sngss7_chan_data_t *sngss7_info;
ftdm_channel_t *ftdmchan;
sngss7_span_data_t *sngss7_span;
sngss7_chan_data_t *sngss7_info = NULL;
ftdm_channel_t *ftdmchan = NULL;
sngss7_span_data_t *sngss7_span = NULL;
int x = 0;
int basefound = 0;
if (range > 31) {
stream->write_function(stream, "Invalid range value %d", range);
@ -1638,42 +1639,45 @@ static ftdm_status_t handle_tx_grs(ftdm_stream_handle_t *stream, int span, int c
if ((ftdmchan->physical_span_id == span) &&
((ftdmchan->physical_chan_id >= chan) && (ftdmchan->physical_chan_id < (chan+range)))) {
/* now that we have the right channel...put a lock on it so no-one else can use it */
ftdm_mutex_lock(ftdmchan->mutex);
ftdm_channel_lock(ftdmchan);
/* if another reset is still in progress, skip this channel */
if (sngss7_test_ckt_flag(sngss7_info, FLAG_GRP_RESET_TX)) {
ftdm_channel_unlock(ftdmchan);
continue;
}
/* check if there is a pending state change|give it a bit to clear */
if (check_for_state_change(ftdmchan)) {
SS7_ERROR("Failed to wait for pending state change on CIC = %d\n", sngss7_info->circuit->cic);
/* check if we need to die */
SS7_ASSERT;
/* unlock the channel again before we exit */
ftdm_mutex_unlock(ftdmchan->mutex);
/* move to the next channel */
ftdm_channel_unlock(ftdmchan);
continue;
} else {
/* throw the grp reset flag */
sngss7_set_ckt_flag(sngss7_info, FLAG_GRP_RESET_TX);
if (ftdmchan->physical_chan_id == chan) {
sngss7_set_ckt_flag(sngss7_info, FLAG_GRP_RESET_BASE);
sngss7_span->tx_grs.circuit = sngss7_info->circuit->id;
sngss7_span->tx_grs.range = range-1;
}
/* set the channel to suspended state */
ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_RESTART);
}
/* unlock the channel again before we exit */
ftdm_mutex_unlock(ftdmchan->mutex);
/* throw the grp reset flag */
sngss7_set_ckt_flag(sngss7_info, FLAG_GRP_RESET_TX);
if (!basefound) {
ftdm_log_chan_msg(ftdmchan, FTDM_LOG_DEBUG, "Setting channel as GRS base\n");
sngss7_set_ckt_flag(sngss7_info, FLAG_GRP_RESET_BASE);
sngss7_info->tx_grs.circuit = sngss7_info->circuit->id;
sngss7_info->tx_grs.range = range - 1;
basefound = 1;
}
} /* if ( span and chan) */
/* set the channel to restart state */
ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_RESTART);
} /* if ( cic != 0) */
ftdm_channel_unlock(ftdmchan);
}
}
/* go the next circuit */
x++;
} /* while (g_ftdm_sngss7_data.cfg.isupCkt[x]id != 0) */
}
x = (g_ftdm_sngss7_data.cfg.procId * 1000) + 1;
while (g_ftdm_sngss7_data.cfg.isupCkt[x].id != 0) {

View File

@ -1910,11 +1910,10 @@ ftdm_status_t handle_grs_req(uint32_t suInstId, uint32_t spInstId, uint32_t circ
{
SS7_FUNC_TRACE_ENTER(__FUNCTION__);
sngss7_chan_data_t *sngss7_info = NULL;
ftdm_channel_t *ftdmchan = NULL;
sngss7_span_data_t *sngss7_span = NULL;
int range;
sngss7_chan_data_t *sngss7_info = NULL;
ftdm_channel_t *ftdmchan = NULL;
sngss7_span_data_t *sngss7_span = NULL;
int range = 0;
/* confirm that the circuit is voice channel */
if (g_ftdm_sngss7_data.cfg.isupCkt[circuit].type != SNG_CKT_VOICE) {
@ -1948,9 +1947,15 @@ ftdm_status_t handle_grs_req(uint32_t suInstId, uint32_t spInstId, uint32_t circ
/* fill in the span structure for this circuit */
sngss7_span = ftdmchan->span->signal_data;
sngss7_span->rx_grs.circuit = circuit;
sngss7_span->rx_grs.range = range;
if (sngss7_info->rx_grs.range) {
SS7_CRITICAL("Cannot handle another GRS on CIC = %d\n", sngss7_info->circuit->cic);
SS7_FUNC_TRACE_EXIT(__FUNCTION__);
return FTDM_FAIL;
}
sngss7_info->rx_grs.circuit = circuit;
sngss7_info->rx_grs.range = range;
ftdm_set_flag(sngss7_span, SNGSS7_RX_GRS_PENDING);
/* the reset will be started in the main thread by "check_if_rx_grs_started" */
SS7_FUNC_TRACE_EXIT(__FUNCTION__);
@ -1962,10 +1967,10 @@ ftdm_status_t handle_grs_rsp(uint32_t suInstId, uint32_t spInstId, uint32_t circ
{
SS7_FUNC_TRACE_ENTER(__FUNCTION__);
sngss7_chan_data_t *sngss7_info = NULL;
ftdm_channel_t *ftdmchan = NULL;
sngss7_span_data_t *sngss7_span = NULL;
int range;
sngss7_chan_data_t *sngss7_info = NULL;
ftdm_channel_t *ftdmchan = NULL;
sngss7_span_data_t *sngss7_span = NULL;
int range = 0;
/* confirm that the circuit is voice channel */
if (g_ftdm_sngss7_data.cfg.isupCkt[circuit].type != SNG_CKT_VOICE) {
@ -1999,17 +2004,24 @@ ftdm_status_t handle_grs_rsp(uint32_t suInstId, uint32_t spInstId, uint32_t circ
/* fill in the span structure for this circuit */
sngss7_span = ftdmchan->span->signal_data;
sngss7_span->rx_gra.circuit = circuit;
sngss7_span->rx_gra.range = range;
if (sngss7_info->rx_gra.range) {
SS7_ERROR("Cannot handle another GRA on CIC = %d\n", sngss7_info->circuit->cic);
SS7_FUNC_TRACE_EXIT(__FUNCTION__);
return FTDM_FAIL;
}
sngss7_info->rx_gra.circuit = circuit;
sngss7_info->rx_gra.range = range;
/* check if there is a cause value in the GRA */
if ((siStaEvnt != NULL) &&
(siStaEvnt->causeDgn.eh.pres == PRSNT_NODEF) &&
(siStaEvnt->causeDgn.causeVal.pres == PRSNT_NODEF)) {
sngss7_span->rx_gra.cause = siStaEvnt->causeDgn.causeVal.val;
sngss7_info->rx_gra.cause = siStaEvnt->causeDgn.causeVal.val;
}
ftdm_set_flag(sngss7_span, SNGSS7_RX_GRA_PENDING);
/* the reset will be started in the main thread by "check_if_rx_gra_started" */
SS7_FUNC_TRACE_EXIT(__FUNCTION__);
@ -2121,9 +2133,12 @@ ftdm_status_t handle_ucic(uint32_t suInstId, uint32_t spInstId, uint32_t circuit
{
SS7_FUNC_TRACE_ENTER(__FUNCTION__);
sngss7_chan_data_t *sngss7_info = NULL;
sngss7_span_data_t *sngss7_span = NULL;
ftdm_channel_t *ftdmchan = NULL;
ftdm_iterator_t *iter = NULL;
ftdm_iterator_t *curr = NULL;
sngss7_chan_data_t *sngss7_info = NULL;
sngss7_chan_data_t *cinfo = NULL;
sngss7_span_data_t *sngss7_span = NULL;
ftdm_channel_t *ftdmchan = NULL;
/* confirm that the circuit is voice channel */
@ -2147,13 +2162,28 @@ ftdm_status_t handle_ucic(uint32_t suInstId, uint32_t spInstId, uint32_t circuit
DECODE_LCC_EVENT(evntType));
}
/* check if we just sent a GRS request...*/
/* find out if the cic belongs to one of our GRS requests, if so,
* all circuits in the request must be blocked */
sngss7_span = ftdmchan->span->signal_data;
if (sngss7_span->tx_grs.circuit > 0) {
/* we need to put all circuits on this UCIC */
sngss7_span->ucic.circuit = sngss7_span->tx_grs.circuit;
sngss7_span->ucic.range = sngss7_span->tx_grs.range;
goto done;
iter = ftdm_span_get_chan_iterator(ftdmchan->span, NULL);
curr = iter;
for (curr = iter; curr; curr = ftdm_iterator_next(curr)) {
ftdm_channel_t *fchan = ftdm_iterator_current(curr);
ftdm_channel_lock(fchan);
cinfo = fchan->call_data;
if (circuit == cinfo->tx_grs.circuit) {
cinfo->ucic.circuit = cinfo->tx_grs.circuit;
cinfo->ucic.range = cinfo->tx_grs.range;
ftdm_set_flag(sngss7_span, SNGSS7_UCIC_PENDING);
ftdm_channel_unlock(fchan);
goto done;
}
ftdm_channel_unlock(fchan);
}
/* lock the channel */
@ -2168,6 +2198,10 @@ ftdm_status_t handle_ucic(uint32_t suInstId, uint32_t spInstId, uint32_t circuit
/* unlock the channel again before we exit */
ftdm_mutex_unlock(ftdmchan->mutex);
done:
if (iter) {
ftdm_iterator_free(iter);
}
SS7_FUNC_TRACE_EXIT(__FUNCTION__);
return FTDM_SUCCESS;
}

View File

@ -328,13 +328,13 @@ static void *ftdm_sangoma_ss7_run(ftdm_thread_t * me, void *obj)
/* unlock the channel */
ftdm_mutex_unlock (ftdmchan->mutex);
}/* while ((ftdmchan = ftdm_queue_dequeue(ftdmspan->pendingchans))) */
}
/* clean out all pending stack events */
while ((sngss7_event = ftdm_queue_dequeue(sngss7_span->event_queue))) {
ftdm_sangoma_ss7_process_stack_event(sngss7_event);
ftdm_safe_free(sngss7_event);
}/* while ((sngss7_event = ftdm_queue_dequeue(ftdmspan->signal_data->event_queue))) */
}
/* signal the core that sig events are queued for processing */
ftdm_span_trigger_signals(ftdmspan);
@ -356,27 +356,27 @@ static void *ftdm_sangoma_ss7_run(ftdm_thread_t * me, void *obj)
break;
/**********************************************************************/
} /* switch ((ftdm_interrupt_wait(ftdm_sangoma_ss7_int, 100))) */
}
/* check if there is a GRA to proccess on the span */
if (sngss7_span->rx_gra.range > 0) {
if (ftdm_test_flag(sngss7_span, SNGSS7_RX_GRA_PENDING)) {
check_if_rx_gra_started(ftdmspan);
} /* if (sngss7->span->rx_gra.range > 0) */
}
/* check if there is a GRS being processed on the span */
if (sngss7_span->rx_grs.range > 0) {
if (ftdm_test_flag(sngss7_span, SNGSS7_RX_GRS_PENDING)) {
/* check if the rx_grs has started */
check_if_rx_grs_started(ftdmspan);
/* check if the rx_grs has cleared */
check_if_rx_grs_processed(ftdmspan);
} /* if (sngss7_span->rx_grs.range > 0) */
}
/* check if there is a UCIC to be processed on the span */
if (sngss7_span->ucic.range > 0) {
if (ftdm_test_flag(sngss7_span, SNGSS7_UCIC_PENDING)) {
/* process the span wide UCIC */
process_span_ucic(ftdmspan);
} /* if (sngss7_span->ucic.range > 0) */
}
/* check each channel on the span to see if there is an un-procressed SUS/RES flag */
check_for_res_sus_flag(ftdmspan);
@ -398,8 +398,8 @@ static void *ftdm_sangoma_ss7_run(ftdm_thread_t * me, void *obj)
default:
SS7_ERROR("%s:Failed to poll span event\n", ftdmspan->name);
/**********************************************************************/
} /* switch (ftdm_span_poll_event(span, 0)) */
} /* master while loop */
}
}
/* clear the IN_THREAD flag so that we know the thread is done */
ftdm_clear_flag (ftdmspan, FTDM_SPAN_IN_THREAD);
@ -423,8 +423,8 @@ ftdm_sangoma_ss7_run_exit:
/******************************************************************************/
static void ftdm_sangoma_ss7_process_stack_event (sngss7_event_data_t *sngss7_event)
{
sngss7_chan_data_t *sngss7_info ;
ftdm_channel_t *ftdmchan;
sngss7_chan_data_t *sngss7_info = NULL;
ftdm_channel_t *ftdmchan = NULL;
/* get the ftdmchan and ss7_chan_data from the circuit */
if (extract_chan_data(sngss7_event->circuit, &sngss7_info, &ftdmchan)) {
@ -432,8 +432,8 @@ static void ftdm_sangoma_ss7_process_stack_event (sngss7_event_data_t *sngss7_ev
return;
}
/* now that we have the right channel...put a lock on it so no-one else can use it */
ftdm_mutex_lock(ftdmchan->mutex);
/* now that we have the right channel ... put a lock on it so no-one else can use it */
ftdm_channel_lock(ftdmchan);
/* while there's a state change present on this channel process it */
ftdm_channel_advance_states(ftdmchan);
@ -496,24 +496,23 @@ static void ftdm_sangoma_ss7_process_stack_event (sngss7_event_data_t *sngss7_ev
SS7_ERROR("Unknown Event Id!\n");
break;
/**************************************************************************/
} /* switch (sngss7_event->event_id) */
}
/* while there's a state change present on this channel process it */
ftdm_channel_advance_states(ftdmchan);
/* unlock the channel */
ftdm_mutex_unlock(ftdmchan->mutex);
ftdm_channel_unlock(ftdmchan);
return;
}
/******************************************************************************/
ftdm_status_t ftdm_sangoma_ss7_process_state_change (ftdm_channel_t * ftdmchan)
{
sngss7_chan_data_t *sngss7_info = ftdmchan->call_data;
sng_isup_inf_t *isup_intf = NULL;
int state_flag = 1;
int i = 0;
sngss7_chan_data_t *sngss7_info = ftdmchan->call_data;
sng_isup_inf_t *isup_intf = NULL;
int state_flag = 1;
int i = 0;
SS7_DEBUG_CHAN(ftdmchan, "ftmod_sangoma_ss7 processing state %s\n", ftdm_channel_state2str (ftdmchan->state));
@ -807,7 +806,7 @@ ftdm_status_t ftdm_sangoma_ss7_process_state_change (ftdm_channel_t * ftdmchan)
/* clear the reset flag */
clear_rx_rsc_flags(sngss7_info);
} /* if (sngss7_test_ckt_flag (sngss7_info, FLAG_RESET_RX)) */
}
/* check if there was a GRS that needs a GRA */
if ((sngss7_test_ckt_flag(sngss7_info, FLAG_GRP_RESET_RX)) &&
@ -815,10 +814,8 @@ ftdm_status_t ftdm_sangoma_ss7_process_state_change (ftdm_channel_t * ftdmchan)
(sngss7_test_ckt_flag(sngss7_info, FLAG_GRP_RESET_RX_CMPLT))) {
/* check if this is the base circuit and send out the GRA
* we insure that this is the last circuit to have the state change queued
*/
sngss7_span_data_t *span = ftdmchan->span->signal_data;
if (span->rx_grs.circuit == sngss7_info->circuit->id) {
* we insure that this is the last circuit to have the state change queued */
if (sngss7_info->rx_grs.range) {
/* send out the GRA */
ft_to_sngss7_gra(ftdmchan);
@ -828,21 +825,22 @@ ftdm_status_t ftdm_sangoma_ss7_process_state_change (ftdm_channel_t * ftdmchan)
/* clear the grp reset flag */
clear_rx_grs_flags(sngss7_info);
}/* if ( sngss7_test_ckt_flag ( sngss7_info, FLAG_GRP_RESET_RX ) ) */
}
/* check if we got the reset response */
if (sngss7_test_ckt_flag(sngss7_info, FLAG_RESET_TX_RSP)) {
/* clear the reset flag */
clear_tx_rsc_flags(sngss7_info);
} /* if (sngss7_test_ckt_flag(sngss7_info, FLAG_RESET_TX_RSP)) */
}
if (sngss7_test_ckt_flag(sngss7_info, FLAG_GRP_RESET_TX_RSP)) {
/* clear the reset flag */
clear_tx_grs_flags(sngss7_info);
/* clean out the spans GRA structure */
clear_rx_gra_data(sngss7_info);
} /* if (sngss7_test_ckt_flag(sngss7_info, FLAG_GRP_RESET_TX_RSP)) */
if (sngss7_info->rx_gra.range) {
/* clean out the spans GRA structure */
clear_rx_gra_data(sngss7_info);
}
}
/* check if we came from reset (aka we just processed a reset) */
if ((ftdmchan->last_state == FTDM_CHANNEL_STATE_RESTART) ||
@ -900,7 +898,7 @@ ftdm_status_t ftdm_sangoma_ss7_process_state_change (ftdm_channel_t * ftdmchan)
ftdm_channel_t *close_chan = ftdmchan;
/* close the channel */
ftdm_channel_close (&close_chan);
} /* if (ftdm_test_flag (ftdmchan, FTDM_CHANNEL_OPEN)) */
}
/* check if there is a glared call that needs to be processed */
if (sngss7_test_ckt_flag(sngss7_info, FLAG_GLARE)) {
@ -918,8 +916,8 @@ ftdm_status_t ftdm_sangoma_ss7_process_state_change (ftdm_channel_t * ftdmchan)
/* clear the glare info */
memset(&sngss7_info->glare, 0x0, sizeof(sngss7_glare_data_t));
} /* if (sngss7_info->glare.circuit != 0) */
} /* if (sngss7_test_ckt_flag(sngss7_info, FLAG_GLARE)) */
}
}
break;
/**************************************************************************/
@ -1265,13 +1263,12 @@ suspend_goto_restart:
break;
/**************************************************************************/
}/*switch (ftdmchan->state) */
#if 1
}
if (state_flag) {
/* clear the state change flag...since we might be setting a new state */
ftdm_channel_complete_state(ftdmchan);
}
#endif
return FTDM_SUCCESS;
}

View File

@ -423,7 +423,7 @@ typedef struct sng_ss7_cfg {
sng_isup_ckt_t isupCkt[10000]; /* KONRAD - only need 2000 ( and 0-1000 aren't used) since other servers are registerd else where */
sng_nsap_t nsap[MAX_NSAPS+1];
sng_isap_t isap[MAX_ISAPS+1];
}sng_ss7_cfg_t;
} sng_ss7_cfg_t;
typedef struct ftdm_sngss7_data {
sng_ss7_cfg_t cfg;
@ -433,7 +433,7 @@ typedef struct ftdm_sngss7_data {
int message_trace;
int message_trace_level;
fio_signal_cb_t sig_cb;
}ftdm_sngss7_data_t;
} ftdm_sngss7_data_t;
typedef struct sngss7_timer_data {
ftdm_timer_id_t hb_timer_id;
@ -442,13 +442,13 @@ typedef struct sngss7_timer_data {
ftdm_sched_callback_t callback;
ftdm_sched_t *sched;
void *sngss7_info;
}sngss7_timer_data_t;
} sngss7_timer_data_t;
typedef struct sngss7_glare_data {
uint32_t spInstId;
uint32_t circuit;
SiConEvnt iam;
}sngss7_glare_data_t;
} sngss7_glare_data_t;
typedef struct sngss7_group_data {
uint32_t circuit;
@ -456,7 +456,7 @@ typedef struct sngss7_group_data {
uint8_t status[255];
uint8_t type;
uint8_t cause;
}sngss7_group_data_t;
} sngss7_group_data_t;
typedef struct sngss7_chan_data {
ftdm_channel_t *ftdmchan;
@ -473,20 +473,24 @@ typedef struct sngss7_chan_data {
void *raw_data; /* send on next sigevent */
sngss7_glare_data_t glare;
sngss7_timer_data_t t35;
}sngss7_chan_data_t;
typedef struct sngss7_span_data {
ftdm_sched_t *sched;
sngss7_group_data_t rx_grs;
sngss7_group_data_t rx_gra;
sngss7_group_data_t tx_grs;
sngss7_group_data_t ucic;
} sngss7_chan_data_t;
#define SNGSS7_RX_GRS_PENDING (1 << 0)
#define SNGSS7_UCIC_PENDING (1 << 1)
#define SNGSS7_RX_GRA_PENDING (1 << 2)
typedef struct sngss7_span_data {
ftdm_sched_t *sched;
uint32_t flags;
sngss7_group_data_t rx_cgb;
sngss7_group_data_t tx_cgb;
sngss7_group_data_t rx_cgu;
sngss7_group_data_t tx_cgu;
sngss7_group_data_t ucic;
ftdm_queue_t *event_queue;
}sngss7_span_data_t;
} sngss7_span_data_t;
typedef struct sngss7_event_data
{
@ -836,7 +840,6 @@ ftdm_status_t append_tknStr_from_sngss7(TknStr str, char *ftdm, TknU8 oddEven);
ftdm_status_t copy_tknStr_to_sngss7(char* str, TknStr *tknStr, TknU8 *oddEven);
int check_for_state_change(ftdm_channel_t *ftdmchan);
int check_cics_in_range(sngss7_chan_data_t *sngss7_info);
int check_for_reset(sngss7_chan_data_t *sngss7_info);
ftdm_status_t extract_chan_data(uint32_t circuit, sngss7_chan_data_t **sngss7_info, ftdm_channel_t **ftdmchan);
unsigned long get_unique_id(void);
@ -875,6 +878,7 @@ ftdm_status_t sngss7_add_raw_data(sngss7_chan_data_t *sngss7_info, uint8_t* data
/* in ftmod_sangoma_ss7_timers.c */
void handle_isup_t35(void *userdata);
/******************************************************************************/
/* MACROS *********************************************************************/

View File

@ -39,32 +39,6 @@
/* GLOBALS ********************************************************************/
/* PROTOTYPES *****************************************************************/
void ft_to_sngss7_iam(ftdm_channel_t * ftdmchan);
void ft_to_sngss7_acm(ftdm_channel_t * ftdmchan);
void ft_to_sngss7_anm(ftdm_channel_t * ftdmchan);
void ft_to_sngss7_rel(ftdm_channel_t * ftdmchan);
void ft_to_sngss7_rlc(ftdm_channel_t * ftdmchan);
void ft_to_sngss7_rsc(ftdm_channel_t * ftdmchan);
void ft_to_sngss7_rsca(ftdm_channel_t * ftdmchan);
void ft_to_sngss7_blo(ftdm_channel_t * ftdmchan);
void ft_to_sngss7_bla(ftdm_channel_t * ftdmchan);
void ft_to_sngss7_ubl(ftdm_channel_t * ftdmchan);
void ft_to_sngss7_uba(ftdm_channel_t * ftdmchan);
void ft_to_sngss7_lpa(ftdm_channel_t * ftdmchan);
void ft_to_sngss7_gra(ftdm_channel_t * ftdmchan);
void ft_to_sngss7_grs(ftdm_channel_t * ftdmchan);
void ft_to_sngss7_cgb(ftdm_channel_t * ftdmchan);
void ft_to_sngss7_cgu(ftdm_channel_t * ftdmchan);
void ft_to_sngss7_cgba(ftdm_channel_t * ftdmchan);
void ft_to_sngss7_cgua(ftdm_channel_t * ftdmchan);
/* FUNCTIONS ******************************************************************/
void ft_to_sngss7_iam (ftdm_channel_t * ftdmchan)
{
@ -447,7 +421,6 @@ void ft_to_sngss7_gra (ftdm_channel_t * ftdmchan)
{
SS7_FUNC_TRACE_ENTER (__FUNCTION__);
sngss7_span_data_t *sngss7_span = ftdmchan->span->signal_data;
sngss7_chan_data_t *sngss7_info = ftdmchan->call_data;
SiStaEvnt gra;
@ -458,11 +431,11 @@ void ft_to_sngss7_gra (ftdm_channel_t * ftdmchan)
/* fill in the range */
gra.rangStat.range.pres = PRSNT_NODEF;
gra.rangStat.range.val = sngss7_span->rx_grs.range;
gra.rangStat.range.val = sngss7_info->rx_grs.range;
/* fill in the status */
gra.rangStat.status.pres = PRSNT_NODEF;
gra.rangStat.status.len = ((sngss7_span->rx_grs.range + 1) >> 3) + (((sngss7_span->rx_grs.range + 1) & 0x07) ? 1 : 0);
gra.rangStat.status.len = ((sngss7_info->rx_grs.range + 1) >> 3) + (((sngss7_info->rx_grs.range + 1) & 0x07) ? 1 : 0);
/* the status field should be 1 if blocked for maintenace reasons
* and 0 is not blocked....since we memset the struct nothing to do
@ -472,15 +445,15 @@ void ft_to_sngss7_gra (ftdm_channel_t * ftdmchan)
sng_cc_sta_request (1,
0,
0,
sngss7_span->rx_grs.circuit,
sngss7_info->rx_grs.circuit,
0,
SIT_STA_GRSRSP,
&gra);
SS7_INFO_CHAN(ftdmchan,"[CIC:%d]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));
(sngss7_info->circuit->cic + sngss7_info->rx_grs.range));
SS7_FUNC_TRACE_EXIT (__FUNCTION__);
@ -492,33 +465,55 @@ void ft_to_sngss7_grs (ftdm_channel_t * ftdmchan)
{
SS7_FUNC_TRACE_ENTER (__FUNCTION__);
sngss7_span_data_t *sngss7_span = ftdmchan->span->signal_data;
ftdm_iterator_t *iter = NULL;
ftdm_iterator_t *curr = NULL;
sngss7_chan_data_t *cinfo = NULL;
sngss7_chan_data_t *sngss7_info = ftdmchan->call_data;
SiStaEvnt grs;
memset (&grs, 0x0, sizeof(grs));
grs.rangStat.eh.pres = PRSNT_NODEF;
grs.rangStat.range.pres = PRSNT_NODEF;
grs.rangStat.range.val = sngss7_span->tx_grs.range;
sng_cc_sta_request (1,
0,
0,
sngss7_span->tx_grs.circuit,
0,
SIT_STA_GRSREQ,
&grs);
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));
iter = ftdm_span_get_chan_iterator(ftdmchan->span, NULL);
curr = iter;
for (curr = iter; curr; curr = ftdm_iterator_next(curr)) {
ftdm_channel_t *fchan = ftdm_iterator_current(curr);
ftdm_channel_lock(fchan);
cinfo = fchan->call_data;
if (!cinfo->tx_grs.range) {
ftdm_channel_unlock(fchan);
continue;
}
memset (&grs, 0x0, sizeof(grs));
grs.rangStat.eh.pres = PRSNT_NODEF;
grs.rangStat.range.pres = PRSNT_NODEF;
grs.rangStat.range.val = cinfo->tx_grs.range;
sng_cc_sta_request (1,
0,
0,
cinfo->tx_grs.circuit,
0,
SIT_STA_GRSREQ,
&grs);
SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Tx GRS (%d:%d)\n",
sngss7_info->circuit->cic,
sngss7_info->circuit->cic,
(sngss7_info->circuit->cic + cinfo->tx_grs.range));
memset(&cinfo->tx_grs, 0, sizeof(cinfo->tx_grs));
ftdm_channel_unlock(fchan);
}
ftdm_iterator_free(iter);
SS7_FUNC_TRACE_EXIT (__FUNCTION__);
return;
}
/******************************************************************************/

View File

@ -47,7 +47,6 @@ uint32_t sngss7_id;
/* PROTOTYPES *****************************************************************/
int check_for_state_change(ftdm_channel_t *ftdmchan);
int check_cics_in_range(sngss7_chan_data_t *sngss7_info);
int check_for_reset(sngss7_chan_data_t *sngss7_info);
unsigned long get_unique_id(void);
@ -61,14 +60,6 @@ ftdm_status_t check_for_res_sus_flag(ftdm_span_t *ftdmspan);
ftdm_status_t process_span_ucic(ftdm_span_t *ftdmspan);
ftdm_status_t clear_rx_grs_flags(sngss7_chan_data_t *sngss7_info);
ftdm_status_t clear_tx_grs_flags(sngss7_chan_data_t *sngss7_info);
ftdm_status_t clear_rx_rsc_flags(sngss7_chan_data_t *sngss7_info);
ftdm_status_t clear_tx_rsc_flags(sngss7_chan_data_t *sngss7_info);
ftdm_status_t clear_rx_grs_data(sngss7_chan_data_t *sngss7_info);
ftdm_status_t clear_rx_gra_data(sngss7_chan_data_t *sngss7_info);
ftdm_status_t clear_tx_grs_data(sngss7_chan_data_t *sngss7_info);
ftdm_status_t encode_subAddrIE_nsap(const char *subAddr, char *subAddrIE, int type);
ftdm_status_t encode_subAddrIE_nat(const char *subAddr, char *subAddrIE, int type);
@ -862,45 +853,6 @@ int check_for_state_change(ftdm_channel_t *ftdmchan)
return 0;
}
/******************************************************************************/
int check_cics_in_range(sngss7_chan_data_t *sngss7_info)
{
#if 0
ftdm_channel_t *tmp_ftdmchan;
sngss7_chan_data_t *tmp_sngss7_info;
int i = 0;
/* check all the circuits in the range to see if we are the last ckt to reset */
for ( i = sngss7_info->grs.circuit; i < ( sngss7_info->grs.range + 1 ); i++ ) {
if ( g_ftdm_sngss7_data.cfg.isupCircuit[i].siglink == 0 ) {
/* get the ftdmchan and ss7_chan_data from the circuit */
if (extract_chan_data(g_ftdm_sngss7_data.cfg.isupCircuit[i].id, &tmp_sngss7_info, &tmp_ftdmchan)) {
SS7_ERROR("Failed to extract channel data for circuit = %d!\n", g_ftdm_sngss7_data.cfg.isupCircuit[i].id);
return 0;
}
/* check if the channel still has the reset flag done is up */
if (!sngss7_test_ckt_flag(tmp_sngss7_info, FLAG_GRP_RESET_RX_DN)) {
SS7_DEBUG_CHAN(tmp_ftdmchan, "[CIC:%d] Still processing reset...\n", tmp_sngss7_info->circuit->cic);
return 0;
}
} /* if not siglink */
} /* for */
SS7_DEBUG("All circuits out of reset: circuit=%d, range=%d\n",
sngss7_info->grs.circuit,
sngss7_info->grs.range);
return 1;
#endif
return 0;
}
/******************************************************************************/
ftdm_status_t extract_chan_data(uint32_t circuit, sngss7_chan_data_t **sngss7_info, ftdm_channel_t **ftdmchan)
{
@ -961,67 +913,86 @@ unsigned long get_unique_id(void)
/******************************************************************************/
ftdm_status_t check_if_rx_grs_started(ftdm_span_t *ftdmspan)
{
ftdm_channel_t *ftdmchan = NULL;
sngss7_chan_data_t *sngss7_info = NULL;
sngss7_span_data_t *sngss7_span = (sngss7_span_data_t *)ftdmspan->signal_data;
int i;
ftdm_iterator_t *iter = NULL;
ftdm_iterator_t *curr = NULL;
ftdm_channel_t *ftdmchan = NULL;
sngss7_chan_data_t *sngss7_info = NULL;
sngss7_chan_data_t *cinfo = NULL;
int i = 0;
iter = ftdm_span_get_chan_iterator(ftdmspan, NULL);
for (curr = iter; curr; curr = ftdm_iterator_next(curr)) {
ftdm_channel_t *fchan = ftdm_iterator_current(curr);
SS7_INFO("Rx GRS (%d:%d)\n",
g_ftdm_sngss7_data.cfg.isupCkt[sngss7_span->rx_grs.circuit].cic,
(g_ftdm_sngss7_data.cfg.isupCkt[sngss7_span->rx_grs.circuit].cic + sngss7_span->rx_grs.range));
ftdm_channel_lock(fchan);
cinfo = fchan->call_data;
for ( i = sngss7_span->rx_grs.circuit; i < (sngss7_span->rx_grs.circuit + sngss7_span->rx_grs.range + 1); i++) {
/* confirm this is a voice channel, otherwise we do nothing */
if (g_ftdm_sngss7_data.cfg.isupCkt[i].type != SNG_CKT_VOICE) {
continue;
}
/* 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);
if (!cinfo->rx_grs.range) {
ftdm_channel_unlock(fchan);
continue;
}
/* check if the GRP_RESET_RX flag is already up */
if (sngss7_test_ckt_flag(sngss7_info, FLAG_GRP_RESET_RX)) {
/* we have already processed this channel...move along */
continue;
SS7_INFO("Rx GRS (%d:%d)\n",
g_ftdm_sngss7_data.cfg.isupCkt[cinfo->rx_grs.circuit].cic,
(g_ftdm_sngss7_data.cfg.isupCkt[cinfo->rx_grs.circuit].cic + cinfo->rx_grs.range));
for (i = cinfo->rx_grs.circuit; i < (cinfo->rx_grs.circuit + cinfo->rx_grs.range + 1); i++) {
/* confirm this is a voice channel, otherwise we do nothing */
if (g_ftdm_sngss7_data.cfg.isupCkt[i].type != SNG_CKT_VOICE) {
continue;
}
/* extract the channel in question */
if (extract_chan_data(i, &sngss7_info, &ftdmchan)) {
SS7_ERROR("Failed to extract channel data for circuit = %d!\n", i);
continue;
}
/* check if the GRP_RESET_RX flag is already up */
if (sngss7_test_ckt_flag(sngss7_info, FLAG_GRP_RESET_RX)) {
/* we have already processed this channel...move along */
continue;
}
/* lock the channel */
ftdm_channel_lock(ftdmchan);
/* clear up any pending state changes */
while (ftdm_test_flag (ftdmchan, FTDM_CHANNEL_STATE_CHANGE)) {
ftdm_sangoma_ss7_process_state_change (ftdmchan);
}
/* flag the channel as having received a reset */
sngss7_set_ckt_flag(sngss7_info, FLAG_GRP_RESET_RX);
switch (ftdmchan->state) {
/**************************************************************************/
case FTDM_CHANNEL_STATE_RESTART:
/* go to idle so that we can redo the restart state*/
ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_IDLE);
break;
/**************************************************************************/
default:
/* set the state of the channel to restart...the rest is done by the chan monitor */
ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_RESTART);
break;
/**************************************************************************/
}
/* unlock the channel again before we exit */
ftdm_channel_unlock(ftdmchan);
}
/* lock the channel */
ftdm_mutex_lock(ftdmchan->mutex);
ftdm_channel_unlock(fchan);
}
/* clear up any pending state changes */
while (ftdm_test_flag (ftdmchan, FTDM_CHANNEL_STATE_CHANGE)) {
ftdm_sangoma_ss7_process_state_change (ftdmchan);
}
/* flag the channel as having received a reset */
sngss7_set_ckt_flag(sngss7_info, FLAG_GRP_RESET_RX);
switch (ftdmchan->state) {
/**************************************************************************/
case FTDM_CHANNEL_STATE_RESTART:
/* go to idle so that we can redo the restart state*/
ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_IDLE);
break;
/**************************************************************************/
default:
/* set the state of the channel to restart...the rest is done by the chan monitor */
ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_RESTART);
break;
/**************************************************************************/
} /* switch (ftdmchan->state) */
/* unlock the channel again before we exit */
ftdm_mutex_unlock(ftdmchan->mutex);
} /* for (chans in GRS */
ftdm_iterator_free(iter);
return FTDM_SUCCESS;
}
@ -1029,191 +1000,244 @@ ftdm_status_t check_if_rx_grs_started(ftdm_span_t *ftdmspan)
/******************************************************************************/
ftdm_status_t check_if_rx_grs_processed(ftdm_span_t *ftdmspan)
{
ftdm_channel_t *ftdmchan = NULL;
sngss7_chan_data_t *sngss7_info = NULL;
sngss7_span_data_t *sngss7_span = (sngss7_span_data_t *)ftdmspan->signal_data;
int i;
int byte = 0;
int bit = 0;
ftdm_iterator_t *iter = NULL;
ftdm_iterator_t *curr = NULL;
ftdm_channel_t *ftdmchan = NULL;
sngss7_chan_data_t *sngss7_info = NULL;
sngss7_chan_data_t *cinfo = NULL;
int i = 0, bn = 0;
int byte = 0, bit = 0;
int cic_start = 0, cic_end = 0, num_cics = 0;
ftdm_bitmap_t *lockmap = 0;
ftdm_size_t mapsize = 0;
/* 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++) {
iter = ftdm_span_get_chan_iterator(ftdmspan, NULL);
for (curr = iter; curr; curr = ftdm_iterator_next(curr)) {
ftdm_channel_t *fchan = ftdm_iterator_current(curr);
ftdm_channel_lock(fchan);
cinfo = fchan->call_data;
if (!cinfo->rx_grs.range) {
ftdm_channel_unlock(fchan);
/* confirm this is a voice channel, otherwise we do nothing */
if (g_ftdm_sngss7_data.cfg.isupCkt[i].type != SNG_CKT_VOICE) {
continue;
}
/* 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;
cic_start = cinfo->rx_grs.circuit;
cic_end = cinfo->rx_grs.circuit + cinfo->rx_grs.range;
num_cics = cinfo->rx_grs.range + 1;
mapsize = (num_cics / FTDM_BITMAP_NBITS) + 1;
lockmap = ftdm_calloc(mapsize, sizeof(*lockmap));
if (!lockmap) {
ftdm_channel_unlock(fchan);
return FTDM_ENOMEM;
}
/* lock the channel */
ftdm_mutex_lock(ftdmchan->mutex);
/* check all the circuits in the range to see if they are done resetting */
for (i = cic_start, bn = 0; i <= cic_end; i++, bn++) {
/* check if there is a state change pending on the channel */
if (!ftdm_test_flag(ftdmchan, FTDM_CHANNEL_STATE_CHANGE)) {
/* check the state to the GRP_RESET_RX_DN flag */
if (!sngss7_test_ckt_flag(sngss7_info, FLAG_GRP_RESET_RX_DN)) {
/* this channel is still resetting...do nothing */
/* confirm this is a voice channel, otherwise we do nothing */
if (g_ftdm_sngss7_data.cfg.isupCkt[i].type != SNG_CKT_VOICE) {
continue;
}
/* 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);
ftdm_assert(FTDM_FALSE, "Failed to extract channel data during GRS\n");
continue;
}
/* lock the channel */
ftdm_channel_lock(ftdmchan);
ftdm_map_set_bit(lockmap, bn);
/* check if there is a state change pending on the channel */
if (!ftdm_test_flag(ftdmchan, FTDM_CHANNEL_STATE_CHANGE)) {
/* check the state to the GRP_RESET_RX_DN flag */
if (!sngss7_test_ckt_flag(sngss7_info, FLAG_GRP_RESET_RX_DN)) {
/* this channel is still resetting...do nothing */
goto GRS_UNLOCK_ALL;
} /* if (!sngss7_test_ckt_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_ckt_flag(sngss7_info, FLAG_GRP_RESET_RX_DN)) */
} else {
/* state change pending */
goto GRS_UNLOCK_ALL;
}
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++) {
/* confirm this is a voice channel, otherwise we do nothing */
if (g_ftdm_sngss7_data.cfg.isupCkt[i].type != SNG_CKT_VOICE) {
continue;
}
/* extract the channel in question */
if (extract_chan_data(i, &sngss7_info, &ftdmchan)) {
SS7_ERROR("Failed to extract channel data for circuit = %d!\n",i);
/* check if we need to die */
SS7_ASSERT;
/* move along */
continue;
SS7_DEBUG("All circuits out of reset for GRS: circuit=%d, range=%d\n", cinfo->rx_grs.circuit, cinfo->rx_grs.range);
for (i = cic_start; i <= cic_end; i++) {
/* confirm this is a voice channel, otherwise we do nothing */
if (g_ftdm_sngss7_data.cfg.isupCkt[i].type != SNG_CKT_VOICE) {
continue;
}
/* 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);
ftdm_assert(FTDM_FALSE, "Failed to extract channel data during GRS\n");
continue;
}
/* throw the GRP reset flag complete flag */
sngss7_set_ckt_flag(sngss7_info, FLAG_GRP_RESET_RX_CMPLT);
/* move the channel to the down state */
ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_DOWN);
/* update the status map if the ckt is in blocked state */
if ((sngss7_test_ckt_blk_flag(sngss7_info, FLAG_CKT_MN_BLOCK_RX)) ||
(sngss7_test_ckt_blk_flag(sngss7_info, FLAG_CKT_MN_BLOCK_TX)) ||
(sngss7_test_ckt_blk_flag(sngss7_info, FLAG_GRP_MN_BLOCK_RX)) ||
(sngss7_test_ckt_blk_flag(sngss7_info, FLAG_GRP_MN_BLOCK_RX))) {
cinfo->rx_grs.status[byte] = (cinfo->rx_grs.status[byte] | (1 << bit));
}
/* update the bit and byte counter*/
bit ++;
if (bit == 8) {
byte++;
bit = 0;
}
}
/* throw the GRP reset flag complete flag */
sngss7_set_ckt_flag(sngss7_info, FLAG_GRP_RESET_RX_CMPLT);
/* move the channel to the down state */
ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_DOWN);
/* update the status map if the ckt is in blocked state */
if ((sngss7_test_ckt_blk_flag(sngss7_info, FLAG_CKT_MN_BLOCK_RX)) ||
(sngss7_test_ckt_blk_flag(sngss7_info, FLAG_CKT_MN_BLOCK_TX)) ||
(sngss7_test_ckt_blk_flag(sngss7_info, FLAG_GRP_MN_BLOCK_RX)) ||
(sngss7_test_ckt_blk_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++) {
for (i = cic_start, bn = 0; i <= cic_end; i++, bn++) {
/* confirm this is a voice channel, otherwise we do nothing */
if (g_ftdm_sngss7_data.cfg.isupCkt[i].type != SNG_CKT_VOICE) {
continue;
}
/* confirm this is a voice channel, otherwise we do nothing */
if (g_ftdm_sngss7_data.cfg.isupCkt[i].type != SNG_CKT_VOICE) {
continue;
/* 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);
ftdm_assert(FTDM_FALSE, "Failed to extract channel data during GRS\n");
continue;
}
if (ftdm_map_test_bit(lockmap, bn)) {
/* unlock the channel */
ftdm_channel_unlock(ftdmchan);
ftdm_map_clear_bit(lockmap, bn);
}
}
/* 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;
}
ftdm_safe_free(lockmap);
/* unlock the channel */
ftdm_mutex_unlock(ftdmchan->mutex);
ftdm_channel_unlock(fchan);
}
ftdm_iterator_free(iter);
return FTDM_SUCCESS;
}
/******************************************************************************/
ftdm_status_t check_if_rx_gra_started(ftdm_span_t *ftdmspan)
{
ftdm_channel_t *ftdmchan = NULL;
sngss7_chan_data_t *sngss7_info = NULL;
sngss7_span_data_t *sngss7_span = (sngss7_span_data_t *)ftdmspan->signal_data;
int i;
ftdm_iterator_t *iter = NULL;
ftdm_iterator_t *curr = NULL;
ftdm_channel_t *ftdmchan = NULL;
sngss7_chan_data_t *sngss7_info = NULL;
sngss7_chan_data_t *cinfo = NULL;
int i = 0;
SS7_INFO("Rx GRA (%d:%d)\n",
g_ftdm_sngss7_data.cfg.isupCkt[sngss7_span->rx_gra.circuit].cic,
(g_ftdm_sngss7_data.cfg.isupCkt[sngss7_span->rx_gra.circuit].cic + sngss7_span->rx_gra.range));
iter = ftdm_span_get_chan_iterator(ftdmspan, NULL);
for (i = sngss7_span->rx_gra.circuit; i < (sngss7_span->rx_gra.circuit + sngss7_span->rx_gra.range + 1); i++) {
for (curr = iter; curr; curr = ftdm_iterator_next(curr)) {
ftdm_channel_t *fchan = ftdm_iterator_current(curr);
ftdm_channel_lock(fchan);
cinfo = fchan->call_data;
if (!cinfo->rx_gra.range) {
ftdm_channel_unlock(fchan);
/* extract the channel in question */
if (extract_chan_data(i, &sngss7_info, &ftdmchan)) {
SS7_ERROR("Failed to extract channel data for circuit = %d!\n", i);
continue;
}
/* check if the channel is already procoessing the GRA */
if (sngss7_test_ckt_flag(sngss7_info, FLAG_GRP_RESET_TX_RSP)) {
/* move along */
continue;
}
SS7_INFO("Rx GRA (%d:%d)\n",
g_ftdm_sngss7_data.cfg.isupCkt[cinfo->rx_gra.circuit].cic,
(g_ftdm_sngss7_data.cfg.isupCkt[cinfo->rx_gra.circuit].cic + cinfo->rx_gra.range));
/* lock the channel */
ftdm_mutex_lock(ftdmchan->mutex);
for (i = cinfo->rx_gra.circuit; i < (cinfo->rx_gra.circuit + cinfo->rx_gra.range + 1); i++) {
/* clear up any pending state changes */
while (ftdm_test_flag (ftdmchan, FTDM_CHANNEL_STATE_CHANGE)) {
ftdm_sangoma_ss7_process_state_change (ftdmchan);
}
switch (ftdmchan->state) {
/**********************************************************************/
case FTDM_CHANNEL_STATE_RESTART:
/* throw the FLAG_RESET_TX_RSP to indicate we have acknowledgement from the remote side */
sngss7_set_ckt_flag(sngss7_info, FLAG_GRP_RESET_TX_RSP);
/* go to DOWN */
ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_DOWN);
break;
/**********************************************************************/
case FTDM_CHANNEL_STATE_DOWN:
/* do nothing, just drop the message */
SS7_DEBUG("Receveived GRA in down state, dropping\n");
break;
/**********************************************************************/
case FTDM_CHANNEL_STATE_TERMINATING:
case FTDM_CHANNEL_STATE_HANGUP:
case FTDM_CHANNEL_STATE_HANGUP_COMPLETE:
/* throw the FLAG_RESET_TX_RSP to indicate we have acknowledgement from the remote side */
sngss7_set_ckt_flag(sngss7_info, FLAG_GRP_RESET_TX_RSP);
break;
/**********************************************************************/
default:
/* ITU Q764-2.9.5.1.c -> release the circuit */
if (sngss7_span->rx_gra.cause != 0) {
ftdmchan->caller_data.hangup_cause = sngss7_span->rx_gra.cause;
} else {
ftdmchan->caller_data.hangup_cause = 98; /* Message not compatiable with call state */
/* 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;
}
/* go to terminating to hang up the call */
ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_TERMINATING);
break;
/**********************************************************************/
/* check if the channel is already processing the GRA */
if (sngss7_test_ckt_flag(sngss7_info, FLAG_GRP_RESET_TX_RSP)) {
/* move along */
continue;
}
/* lock the channel */
ftdm_channel_lock(ftdmchan);
/* clear up any pending state changes */
while (ftdm_test_flag (ftdmchan, FTDM_CHANNEL_STATE_CHANGE)) {
ftdm_sangoma_ss7_process_state_change (ftdmchan);
}
switch (ftdmchan->state) {
/**********************************************************************/
case FTDM_CHANNEL_STATE_RESTART:
/* throw the FLAG_RESET_TX_RSP to indicate we have acknowledgement from the remote side */
sngss7_set_ckt_flag(sngss7_info, FLAG_GRP_RESET_TX_RSP);
/* go to DOWN */
ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_DOWN);
break;
/**********************************************************************/
case FTDM_CHANNEL_STATE_DOWN:
/* do nothing, just drop the message */
SS7_DEBUG("Receveived GRA in down state, dropping\n");
break;
/**********************************************************************/
case FTDM_CHANNEL_STATE_TERMINATING:
case FTDM_CHANNEL_STATE_HANGUP:
case FTDM_CHANNEL_STATE_HANGUP_COMPLETE:
/* throw the FLAG_RESET_TX_RSP to indicate we have acknowledgement from the remote side */
sngss7_set_ckt_flag(sngss7_info, FLAG_GRP_RESET_TX_RSP);
break;
/**********************************************************************/
default:
/* ITU Q764-2.9.5.1.c -> release the circuit */
if (cinfo->rx_gra.cause != 0) {
ftdmchan->caller_data.hangup_cause = cinfo->rx_gra.cause;
} else {
ftdmchan->caller_data.hangup_cause = 98; /* Message not compatiable with call state */
}
/* go to terminating to hang up the call */
ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_TERMINATING);
break;
/**********************************************************************/
}
ftdm_channel_unlock(ftdmchan);
}
/* unlock the channel again before we exit */
ftdm_mutex_unlock(ftdmchan->mutex);
} /* for ( circuits in request */
ftdm_channel_unlock(fchan);
}
ftdm_iterator_free(iter);
return FTDM_SUCCESS;
}
@ -1286,41 +1310,66 @@ ftdm_status_t check_for_res_sus_flag(ftdm_span_t *ftdmspan)
/******************************************************************************/
ftdm_status_t process_span_ucic(ftdm_span_t *ftdmspan)
{
ftdm_channel_t *ftdmchan = NULL;
sngss7_chan_data_t *sngss7_info = NULL;
sngss7_span_data_t *sngss7_span = (sngss7_span_data_t *)ftdmspan->signal_data;
int i;
ftdm_iterator_t *iter = NULL;
ftdm_iterator_t *curr = NULL;
ftdm_channel_t *ftdmchan = NULL;
sngss7_chan_data_t *sngss7_info = NULL;
sngss7_chan_data_t *cinfo = NULL;
sngss7_span_data_t *sngss7_span = (sngss7_span_data_t *)ftdmspan->signal_data;
int i = 0;
for (i = sngss7_span->ucic.circuit; i < (sngss7_span->ucic.circuit + sngss7_span->ucic.range + 1); i++) {
iter = ftdm_span_get_chan_iterator(ftdmspan, NULL);
curr = iter;
for (curr = iter; curr; curr = ftdm_iterator_next(curr)) {
ftdm_channel_t *fchan = ftdm_iterator_current(curr);
ftdm_channel_lock(fchan);
cinfo = fchan->call_data;
if (!cinfo->ucic.range) {
ftdm_channel_unlock(fchan);
/* 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;
}
/* lock the channel */
ftdm_mutex_lock(ftdmchan->mutex);
for (i = cinfo->ucic.circuit; i < (cinfo->ucic.circuit + cinfo->ucic.range + 1); i++) {
SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Rx UCIC\n", sngss7_info->circuit->cic);
/* 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;
}
/* clear up any pending state changes */
while (ftdm_test_flag (ftdmchan, FTDM_CHANNEL_STATE_CHANGE)) {
ftdm_sangoma_ss7_process_state_change (ftdmchan);
/* lock the channel */
ftdm_channel_lock(ftdmchan);
SS7_INFO_CHAN(ftdmchan, "[CIC:%d]Rx UCIC\n", sngss7_info->circuit->cic);
/* clear up any pending state changes */
while (ftdm_test_flag (ftdmchan, FTDM_CHANNEL_STATE_CHANGE)) {
ftdm_sangoma_ss7_process_state_change (ftdmchan);
}
/* throw the ckt block flag */
sngss7_set_ckt_blk_flag(sngss7_info, FLAG_CKT_UCIC_BLOCK);
/* set the channel to suspended state */
ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_SUSPENDED);
/* unlock the channel again before we exit */
ftdm_channel_unlock(ftdmchan);
}
/* clear out the ucic data since we're done with it */
memset(&cinfo->ucic, 0, sizeof(cinfo->ucic));
/* throw the ckt block flag */
sngss7_set_ckt_blk_flag(sngss7_info, FLAG_CKT_UCIC_BLOCK);
/* set the channel to suspended state */
ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_SUSPENDED);
/* unlock the channel again before we exit */
ftdm_mutex_unlock(ftdmchan->mutex);
ftdm_channel_unlock(fchan);
}
/* clear out the ucic data since we're done with it */
memset(&sngss7_span->ucic, 0x0, sizeof(sngss7_group_data_t));
ftdm_clear_flag(sngss7_span, SNGSS7_UCIC_PENDING);
ftdm_iterator_free(iter);
return FTDM_SUCCESS;
}
@ -1339,11 +1388,36 @@ ftdm_status_t clear_rx_grs_flags(sngss7_chan_data_t *sngss7_info)
/******************************************************************************/
ftdm_status_t clear_rx_grs_data(sngss7_chan_data_t *sngss7_info)
{
ftdm_channel_t *ftdmchan = sngss7_info->ftdmchan;
sngss7_span_data_t *sngss7_span = ftdmchan->span->signal_data;
ftdm_iterator_t *iter = NULL;
ftdm_iterator_t *curr = NULL;
sngss7_chan_data_t *cinfo = NULL;
ftdm_channel_t *ftdmchan = sngss7_info->ftdmchan;
sngss7_span_data_t *sngss7_span = (sngss7_span_data_t *)ftdmchan->span->signal_data;
/* clear the rx_grs data fields */
memset(&sngss7_span->rx_grs, 0x0, sizeof(sngss7_group_data_t));
memset(&sngss7_info->rx_grs, 0, sizeof(sngss7_info->rx_grs));
iter = ftdm_span_get_chan_iterator(ftdmchan->span, NULL);
curr = iter;
for (curr = iter; curr; curr = ftdm_iterator_next(curr)) {
ftdm_channel_t *fchan = ftdm_iterator_current(curr);
ftdm_channel_lock(fchan);
cinfo = fchan->call_data;
if (cinfo->rx_grs.range) {
/* there is still another grs pending, do not clear the SNGSS7_RX_GRS_PENDING flag yet */
ftdm_channel_unlock(fchan);
goto done;
}
ftdm_channel_unlock(fchan);
}
/* if we're here is because there is no other grs going on now in this span */
ftdm_clear_flag(sngss7_span, SNGSS7_RX_GRS_PENDING);
done:
ftdm_iterator_free(iter);
return FTDM_SUCCESS;
}
@ -1351,11 +1425,38 @@ ftdm_status_t clear_rx_grs_data(sngss7_chan_data_t *sngss7_info)
/******************************************************************************/
ftdm_status_t clear_rx_gra_data(sngss7_chan_data_t *sngss7_info)
{
ftdm_channel_t *ftdmchan = sngss7_info->ftdmchan;
sngss7_span_data_t *sngss7_span = ftdmchan->span->signal_data;
ftdm_iterator_t *iter = NULL;
ftdm_iterator_t *curr = NULL;
sngss7_chan_data_t *cinfo = NULL;
ftdm_channel_t *ftdmchan = sngss7_info->ftdmchan;
sngss7_span_data_t *sngss7_span = ftdmchan->span->signal_data;
/* clear the rx_grs data fields */
memset(&sngss7_span->rx_gra, 0x0, sizeof(sngss7_group_data_t));
memset(&sngss7_info->rx_gra, 0, sizeof(sngss7_info->rx_gra));
iter = ftdm_span_get_chan_iterator(ftdmchan->span, NULL);
curr = iter;
for (curr = iter; curr; curr = ftdm_iterator_next(curr)) {
ftdm_channel_t *fchan = ftdm_iterator_current(curr);
ftdm_channel_lock(fchan);
cinfo = fchan->call_data;
if (cinfo->rx_gra.range) {
/* there is still another gra pending, do not clear the SNGSS7_RX_GRA_PENDING flag yet */
ftdm_channel_unlock(fchan);
goto done;
}
ftdm_channel_unlock(fchan);
}
/* if we're here is because there is no other gra pending in this span */
ftdm_clear_flag(sngss7_span, SNGSS7_RX_GRA_PENDING);
done:
ftdm_iterator_free(iter);
return FTDM_SUCCESS;
}
@ -1374,12 +1475,8 @@ ftdm_status_t clear_tx_grs_flags(sngss7_chan_data_t *sngss7_info)
/******************************************************************************/
ftdm_status_t clear_tx_grs_data(sngss7_chan_data_t *sngss7_info)
{
ftdm_channel_t *ftdmchan = sngss7_info->ftdmchan;
sngss7_span_data_t *sngss7_span = ftdmchan->span->signal_data;
/* clear the rx_grs data fields */
memset(&sngss7_span->tx_grs, 0x0, sizeof(sngss7_group_data_t));
/* clear everything up */
memset(&sngss7_info->tx_grs, 0, sizeof(sngss7_info->tx_grs));
return FTDM_SUCCESS;
}

View File

@ -43,14 +43,14 @@ FT_DECLARE(void) ftdm_thread_override_default_stacksize(ftdm_size_t size);
FT_DECLARE(ftdm_status_t) ftdm_mutex_create(ftdm_mutex_t **mutex);
FT_DECLARE(ftdm_status_t) ftdm_mutex_destroy(ftdm_mutex_t **mutex);
#define ftdm_mutex_lock(_x) _ftdm_mutex_lock(_x)
FT_DECLARE(ftdm_status_t) _ftdm_mutex_lock(ftdm_mutex_t *mutex);
#define ftdm_mutex_lock(_x) _ftdm_mutex_lock(__FILE__, __LINE__, __FUNCTION__, _x)
FT_DECLARE(ftdm_status_t) _ftdm_mutex_lock(const char *file, int line, const char *func, ftdm_mutex_t *mutex);
#define ftdm_mutex_trylock(_x) _ftdm_mutex_trylock(_x)
FT_DECLARE(ftdm_status_t) _ftdm_mutex_trylock(ftdm_mutex_t *mutex);
#define ftdm_mutex_trylock(_x) _ftdm_mutex_trylock(__FILE__, __LINE__, __FUNCTION__, _x)
FT_DECLARE(ftdm_status_t) _ftdm_mutex_trylock(const char *file, int line, const char *func, ftdm_mutex_t *mutex);
#define ftdm_mutex_unlock(_x) _ftdm_mutex_unlock(_x)
FT_DECLARE(ftdm_status_t) _ftdm_mutex_unlock(ftdm_mutex_t *mutex);
#define ftdm_mutex_unlock(_x) _ftdm_mutex_unlock(__FILE__, __LINE__, __FUNCTION__, _x)
FT_DECLARE(ftdm_status_t) _ftdm_mutex_unlock(const char *file, int line, const char *func, ftdm_mutex_t *mutex);
FT_DECLARE(ftdm_status_t) ftdm_interrupt_create(ftdm_interrupt_t **cond, ftdm_socket_t device);
FT_DECLARE(ftdm_status_t) ftdm_interrupt_destroy(ftdm_interrupt_t **cond);

View File

@ -719,8 +719,8 @@ FT_DECLARE(ftdm_status_t) ftdm_sigmsg_set_raw_data(ftdm_sigmsg_t *sigmsg, void *
*/
#define ftdm_socket_close(it) if (it > -1) { close(it); it = -1;}
#define ftdm_channel_lock(chan) ftdm_mutex_lock(chan->mutex)
#define ftdm_channel_unlock(chan) ftdm_mutex_unlock(chan->mutex)
#define ftdm_channel_lock(chan) ftdm_mutex_lock((chan)->mutex)
#define ftdm_channel_unlock(chan) ftdm_mutex_unlock((chan)->mutex)
#define ftdm_log_throttle(level, ...) \
time_current_throttle_log = ftdm_current_time_in_ms(); \
@ -777,6 +777,13 @@ static __inline__ int16_t ftdm_saturated_add(int16_t sample1, int16_t sample2)
return (int16_t)addres;
}
/* Bitmap helper functions */
typedef long ftdm_bitmap_t;
#define FTDM_BITMAP_NBITS (sizeof(ftdm_bitmap_t) * 8)
#define ftdm_map_set_bit(map, bit) (map[(bit/FTDM_BITMAP_NBITS)] |= ((ftdm_bitmap_t)1 << (bit % FTDM_BITMAP_NBITS)))
#define ftdm_map_clear_bit(map, bit) (map[(bit/FTDM_BITMAP_NBITS)] &= ~((ftdm_bitmap_t)1 << (bit % FTDM_BITMAP_NBITS)))
#define ftdm_map_test_bit(map, bit) (map[(bit/FTDM_BITMAP_NBITS)] & ((ftdm_bitmap_t)1 << (bit % FTDM_BITMAP_NBITS)))
#ifdef __cplusplus
}
#endif