static ftdm_status_t handle_show_blocks(ftdm_stream_handle_t *stream, int span, int chan, int verbose);
static ftdm_status_t handle_show_status(ftdm_stream_handle_t *stream, int span, int chan, int verbose);
+static ftdm_status_t handle_tx_rsc(ftdm_stream_handle_t *stream, int span, int chan, int verbose);
+static ftdm_status_t handle_tx_grs(ftdm_stream_handle_t *stream, int span, int chan, int range, int verbose);
+
static ftdm_status_t handle_status_link(ftdm_stream_handle_t *stream, char *name);
static ftdm_status_t handle_status_linkset(ftdm_stream_handle_t *stream, char *name);
{
char *mycmd = NULL;
char *argv[10] = { 0 };
- int argc = 0;
- int span = 0;
- int chan = 0;
- int trace = 0;
- int trace_level = 7;
- int verbose = 1;
- int c = 0;
+ int argc = 0;
+ int span = 0;
+ int chan = 0;
+ int range = 0;
+ int trace = 0;
+ int trace_level = 7;
+ int verbose = 1;
+ int c = 0;
if (data) {
mycmd = ftdm_strdup(data);
/**********************************************************************/
}
/**************************************************************************/
+ } else if (!strcasecmp(argv[c], "rsc")) {
+ /**************************************************************************/
+ if (check_arg_count(argc, 2)) goto handle_cli_error_argc;
+ c++;
+
+ if (!strcasecmp(argv[c], "span")) {
+ /**********************************************************************/
+ if (check_arg_count(argc, 5)) goto handle_cli_error_argc;
+
+ if (extract_span_chan(argv, c, &span, &chan)) goto handle_cli_error_span_chan;
+
+ handle_tx_rsc(stream, span, chan, verbose);
+ /**********************************************************************/
+ } else {
+ /**********************************************************************/
+ stream->write_function(stream, "Unknown \"rsc\" command\n");
+ goto handle_cli_error;
+ /**********************************************************************/
+ }
+ /**************************************************************************/
+ } else if (!strcasecmp(argv[c], "grs")) {
+ /**************************************************************************/
+ if (check_arg_count(argc, 2)) goto handle_cli_error_argc;
+ c++;
+
+ if (!strcasecmp(argv[c], "span")) {
+ /**********************************************************************/
+ if (check_arg_count(argc, 5)) goto handle_cli_error_argc;
+
+ if (extract_span_chan(argv, c, &span, &chan)) goto handle_cli_error_span_chan;
+ c = c + 4;
+
+ if (check_arg_count(argc, 7)) goto handle_cli_error_argc;
+
+ if (!strcasecmp(argv[c], "range")) {
+ /******************************************************************/
+ c++;
+ range = atoi(argv[c]);
+ /******************************************************************/
+ } else {
+ /******************************************************************/
+ stream->write_function(stream, "Unknown \"grs range\" command\n");
+ goto handle_cli_error;
+ /******************************************************************/
+ }
+
+ handle_tx_grs(stream, span, chan, range, verbose);
+ /**********************************************************************/
+ } else {
+ /**********************************************************************/
+ stream->write_function(stream, "Unknown \"grs\" command\n");
+ goto handle_cli_error;
+ /**********************************************************************/
+ }
+ /**************************************************************************/
} else {
/**************************************************************************/
goto handle_cli_error;
stream->write_function(stream, "Ftmod_sangoma_ss7 circuit control:\n");
stream->write_function(stream, "ftdm ss7 block span X chan Y\n");
stream->write_function(stream, "ftdm ss7 unblk span X chan Y\n");
+ stream->write_function(stream, "ftdm ss7 rsc span X chan Y\n");
+ stream->write_function(stream, "ftdm ss7 grs span X chan Y range Z\n");
stream->write_function(stream, "\n");
return FTDM_SUCCESS;
return FTDM_SUCCESS;
}
+/******************************************************************************/
+static ftdm_status_t handle_tx_rsc(ftdm_stream_handle_t *stream, int span, int chan, int verbose)
+{
+ int x;
+ sngss7_chan_data_t *ss7_info;
+ ftdm_channel_t *ftdmchan;
+ int lspan;
+ int lchan;
+
+ x=1;
+ while (g_ftdm_sngss7_data.cfg.isupCkt[x].id != 0) {
+ if (g_ftdm_sngss7_data.cfg.isupCkt[x].type == VOICE) {
+ ss7_info = (sngss7_chan_data_t *)g_ftdm_sngss7_data.cfg.isupCkt[x].obj;
+ ftdmchan = ss7_info->ftdmchan;
+
+ /* if span == 0 then all spans should be printed */
+ if (span == 0) {
+ lspan = ftdmchan->physical_span_id;
+ } else {
+ lspan = span;
+ }
+
+ /* if chan == 0 then all chans should be printed */
+ if (chan == 0) {
+ lchan = ftdmchan->physical_chan_id;
+ } else {
+ lchan = chan;
+ }
+
+ if ((ftdmchan->physical_span_id == lspan) && (ftdmchan->physical_chan_id == lchan)) {
+ /* now that we have the right channel...put a lock on it so no-one else can use it */
+ ftdm_mutex_lock(ftdmchan->mutex);
+
+ /* check if there is a pending state change|give it a bit to clear */
+ if (check_for_state_change(ftdmchan)) {
+ SS7_ERROR("Failed to wait for pending state change on CIC = %d\n", ss7_info->circuit->cic);
+ SS7_ASSERT;
+ } else {
+ /* throw the ckt block flag */
+ sngss7_set_flag(ss7_info, FLAG_RESET_TX);
+
+ /* set the channel to suspended state */
+ ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_RESTART);
+ }
+
+ /* unlock the channel again before we exit */
+ ftdm_mutex_unlock(ftdmchan->mutex);
+
+ } /* if ( span and chan) */
+
+ } /* if ( cic != 0) */
+
+ /* go the next circuit */
+ x++;
+ } /* while (g_ftdm_sngss7_data.cfg.isupCkt[x]id != 0) */
+
+
+ return FTDM_SUCCESS;
+}
+
+/******************************************************************************/
+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;
+
+ if (range > 31) {
+ stream->write_function(stream, "Invalid range value %d", range);
+ return FTDM_SUCCESS;
+ }
+
+ x=1;
+ while (g_ftdm_sngss7_data.cfg.isupCkt[x].id != 0) {
+ if (g_ftdm_sngss7_data.cfg.isupCkt[x].type == VOICE) {
+
+ sngss7_info = (sngss7_chan_data_t *)g_ftdm_sngss7_data.cfg.isupCkt[x].obj;
+ ftdmchan = sngss7_info->ftdmchan;
+ sngss7_span = ftdmchan->span->mod_data;
+
+ 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);
+
+ /* 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);
+ SS7_ASSERT;
+ } else {
+ /* throw the grp reset flag */
+ sngss7_set_flag(sngss7_info, FLAG_GRP_RESET_TX);
+ if (ftdmchan->physical_chan_id == chan) {
+ sngss7_set_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_locked(ftdmchan, FTDM_CHANNEL_STATE_RESTART);
+
+ }
+
+ /* unlock the channel again before we exit */
+ ftdm_mutex_unlock(ftdmchan->mutex);
+
+ } /* if ( span and chan) */
+
+ } /* if ( cic != 0) */
+
+ /* go the next circuit */
+ x++;
+ } /* while (g_ftdm_sngss7_data.cfg.isupCkt[x]id != 0) */
+
+
+ return FTDM_SUCCESS;
+}
+
/******************************************************************************/
static ftdm_status_t extract_span_chan(char *argv[10], int pos, int *span, int *chan)
{
SS7_ASSERT;
};
- if (sngss7_info->glare.spInstId > 0) {
+ if (sngss7_test_flag(sngss7_info, FLAG_GLARE)) {
SS7_MSG_TRACE(ftdmchan, sngss7_info, "Rx IAM (glare detected on circuit)\n");
} else {
SS7_MSG_TRACE(ftdmchan, sngss7_info, "Rx IAM\n");
/**************************************************************************/
default:
- /* fill in the channels SS7 Stack information */
- sngss7_info->suInstId = get_unique_id();
- sngss7_info->spInstId = spInstId;
-
/* throw the reset flag */
sngss7_set_flag(sngss7_info, FLAG_RESET_RX);
{
SS7_FUNC_TRACE_ENTER(__FUNCTION__);
- sngss7_chan_data_t *sngss7_info = NULL;
- ftdm_channel_t *ftdmchan = NULL;
- sngss7_span_data_t *span = NULL;
+ sngss7_chan_data_t *sngss7_info = NULL;
+ ftdm_channel_t *ftdmchan = NULL;
+ sngss7_span_data_t *sngss7_span = NULL;
int range;
int x;
};
/* fill in the span structure for this circuit */
- span = ftdmchan->span->mod_data;
- span->grs.circuit = circuit;
- span->grs.range = range;
+ sngss7_span = ftdmchan->span->mod_data;
+ sngss7_span->rx_grs.circuit = circuit;
+ sngss7_span->rx_grs.range = range;
- SS7_DEBUG_CHAN(ftdmchan, "Rx GRS (%d:%d)\n",
+ SS7_INFO_CHAN(ftdmchan, "Rx GRS (%d:%d)\n",
g_ftdm_sngss7_data.cfg.isupCkt[circuit].cic,
(g_ftdm_sngss7_data.cfg.isupCkt[circuit].cic + range));
SS7_ASSERT;
};
- SS7_DEBUG_CHAN(ftdmchan, "Rx GRA (%d:%d)\n",
+ SS7_INFO_CHAN(ftdmchan, "Rx GRA (%d:%d)\n",
g_ftdm_sngss7_data.cfg.isupCkt[circuit].cic,
(g_ftdm_sngss7_data.cfg.isupCkt[circuit].cic + range));
sngss7_span = (sngss7_span_data_t *)ftdmspan->mod_data;
/* check if there is a GRS being processed on the span */
- if (sngss7_span->grs.range > 0) {
+ if (sngss7_span->rx_grs.range > 0) {
ftdm_log(FTDM_LOG_DEBUG, "Found Rx GRS on span %d...checking circuits\n", ftdmspan->span_id);
/*SS7_DEBUG("Found Rx GRS on span %d...checking circuits\n", ftdmspan->span_id);*/
/* check all the circuits in the range to see if they are done resetting */
- for ( i = sngss7_span->grs.circuit; i < (sngss7_span->grs.circuit + sngss7_span->grs.range + 1); i++) {
+ for ( i = sngss7_span->rx_grs.circuit; i < (sngss7_span->rx_grs.circuit + sngss7_span->rx_grs.range + 1); i++) {
/* extract the channel in question */
if (extract_chan_data(i, &sngss7_info, &ftdmchan)) {
} /* for ( i = circuit; i < (circuit + range + 1); i++) */
SS7_DEBUG("All circuits out of reset for GRS: circuit=%d, range=%d\n",
- sngss7_span->grs.circuit,
- sngss7_span->grs.range);
+ 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->grs.circuit; i < (sngss7_span->grs.circuit + sngss7_span->grs.range + 1); i++) {
+ for ( i = sngss7_span->rx_grs.circuit; i < (sngss7_span->rx_grs.circuit + sngss7_span->rx_grs.range + 1); i++) {
/* extract the channel in question */
if (extract_chan_data(i, &sngss7_info, &ftdmchan)) {
} /* for ( i = circuit; i < (circuit + range + 1); i++) */
GRS_UNLOCK_ALL:
- for ( i = sngss7_span->grs.circuit; i < (sngss7_span->grs.circuit + sngss7_span->grs.range + 1); i++) {
+ for ( i = sngss7_span->rx_grs.circuit; i < (sngss7_span->rx_grs.circuit + sngss7_span->rx_grs.range + 1); i++) {
/* extract the channel in question */
if (extract_chan_data(i, &sngss7_info, &ftdmchan)) {
SS7_ERROR("Failed to extract channel data for circuit = %d!\n", i);
* we insure that this is the last circuit to have the state change queued
*/
sngss7_span_data_t *span = ftdmchan->span->mod_data;
- if (span->grs.circuit == sngss7_info->circuit->id) {
+ if (span->rx_grs.circuit == sngss7_info->circuit->id) {
/* send out the GRA */
ft_to_sngss7_gra(ftdmchan);
/* clean out the spans GRS structure */
sngss7_span_data_t *span = ftdmchan->span->mod_data;
- span->grs.circuit = 0;
- span->grs.range = 0;
+ span->rx_grs.circuit = 0;
+ span->rx_grs.range = 0;
}
/* clear the grp reset flag */
if (sngss7_test_flag(sngss7_info, FLAG_RESET_TX_RSP)) {
/* clear the reset flag */
sngss7_clear_flag(sngss7_info, FLAG_RESET_TX_RSP);
+ sngss7_clear_flag(sngss7_info, FLAG_RESET_SENT);
sngss7_clear_flag(sngss7_info, FLAG_RESET_TX);
}
{
ftdm_channel_t *ftdmchan = NULL;
sngss7_chan_data_t *sngss7_info = NULL;
+ sngss7_span_data_t *sngss7_span = NULL;
int x;
/* extract the channel structure and sngss7 channel data */
ftdmchan = span->channels[x];
sngss7_info = ftdmchan->call_data;
+ sngss7_span = ftdmchan->span->mod_data;
/* lock the channel */
ftdm_mutex_lock(ftdmchan->mutex);
sngss7_set_flag(sngss7_info, FLAG_GRP_RESET_TX);
if (x == 1) {
sngss7_set_flag(sngss7_info, FLAG_GRP_RESET_BASE);
+ sngss7_span->tx_grs.circuit = sngss7_info->circuit->id;
+ sngss7_span->tx_grs.range = span->chan_count -1;
}
/* throw the channel to suspend */
typedef struct sngss7_span_data {
ftdm_sched_t *sched;
- sngss7_group_data_t grs;
+ sngss7_group_data_t rx_grs;
+ sngss7_group_data_t tx_grs;
ftdm_queue_t *event_queue;
}sngss7_span_data_t;
{
SS7_FUNC_TRACE_ENTER (__FUNCTION__);
- sngss7_span_data_t *span = ftdmchan->span->mod_data;
+ sngss7_span_data_t *sngss7_span = ftdmchan->span->mod_data;
sngss7_chan_data_t *sngss7_info = ftdmchan->call_data;
SiStaEvnt gra;
/* fill in the range */
gra.rangStat.range.pres = PRSNT_NODEF;
- gra.rangStat.range.val = span->grs.range;
+ gra.rangStat.range.val = sngss7_span->rx_grs.range;
/* fill in the status */
gra.rangStat.status.pres = PRSNT_NODEF;
- gra.rangStat.status.len = ((span->grs.range + 1) >> 3) + (((span->grs.range + 1) & 0x07) ? 1 : 0);
+ gra.rangStat.status.len = ((sngss7_span->rx_grs.range + 1) >> 3) + (((sngss7_span->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
sng_cc_sta_request (1,
0,
0,
- span->grs.circuit,
+ sngss7_span->rx_grs.circuit,
0,
SIT_STA_GRSRSP,
&gra);
- SS7_MSG_TRACE(ftdmchan, sngss7_info, "Tx GRA\n");
+ SS7_INFO_CHAN(ftdmchan, "Tx GRA (%d:%d)\n",
+ sngss7_info->circuit->cic,
+ (sngss7_info->circuit->cic + sngss7_span->rx_grs.range));
SS7_FUNC_TRACE_EXIT (__FUNCTION__);
return;
/******************************************************************************/
void ft_to_sngss7_grs (ftdm_channel_t * ftdmchan)
{
-SS7_FUNC_TRACE_ENTER (__FUNCTION__);
-
-sngss7_chan_data_t *sngss7_info = ftdmchan->call_data;
-ftdm_span_t *span = ftdmchan->span;
-
-SiStaEvnt grs;
-
-memset (&grs, 0x0, sizeof (grs));
-
-grs.rangStat.eh.pres = PRSNT_NODEF;
-grs.rangStat.range.pres = PRSNT_NODEF;
-grs.rangStat.range.val = span->chan_count-1;
-
-sng_cc_sta_request (1,
- 0,
- 0,
- sngss7_info->circuit->id,
- 0,
- SIT_STA_GRSREQ,
- &grs);
-
-
-SS7_MSG_TRACE(ftdmchan, sngss7_info, "Tx GRS\n");
-
-SS7_FUNC_TRACE_EXIT (__FUNCTION__);
+ SS7_FUNC_TRACE_ENTER (__FUNCTION__);
+
+ sngss7_span_data_t *sngss7_span = ftdmchan->span->mod_data;
+ 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, "Tx GRS (%d:%d)\n",
+ sngss7_info->circuit->cic,
+ (sngss7_info->circuit->cic + sngss7_span->tx_grs.range));
+
+ SS7_FUNC_TRACE_EXIT (__FUNCTION__);
return;
}