freetdm: ss7 - added cli support to send GRS and RSC

This commit is contained in:
Konrad Hammel 2010-09-02 17:33:17 -04:00
parent 70b0e4bd51
commit af3285ab61
5 changed files with 245 additions and 60 deletions

View File

@ -60,6 +60,9 @@ static ftdm_status_t handle_show_flags(ftdm_stream_handle_t *stream, int span, i
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);
@ -72,13 +75,14 @@ ftdm_status_t ftdm_sngss7_handle_cli_cmd(ftdm_stream_handle_t *stream, const cha
{
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);
@ -332,6 +336,61 @@ ftdm_status_t ftdm_sngss7_handle_cli_cmd(ftdm_stream_handle_t *stream, const cha
/**********************************************************************/
}
/**************************************************************************/
} 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;
@ -376,6 +435,8 @@ static ftdm_status_t handle_print_usuage(ftdm_stream_handle_t *stream)
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;
@ -1090,6 +1151,125 @@ static ftdm_status_t handle_set_uninhibit(ftdm_stream_handle_t *stream, char *na
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)
{

View File

@ -99,7 +99,7 @@ ftdm_status_t handle_con_ind(uint32_t suInstId, uint32_t spInstId, uint32_t circ
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");
@ -569,10 +569,6 @@ ftdm_status_t handle_rel_ind(uint32_t suInstId, uint32_t spInstId, uint32_t circ
/**************************************************************************/
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);
@ -1685,9 +1681,9 @@ 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 *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;
@ -1725,11 +1721,11 @@ ftdm_status_t handle_grs_req(uint32_t suInstId, uint32_t spInstId, uint32_t circ
};
/* 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));
@ -1800,7 +1796,7 @@ ftdm_status_t handle_grs_rsp(uint32_t suInstId, uint32_t spInstId, uint32_t circ
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));

View File

@ -345,12 +345,12 @@ static void *ftdm_sangoma_ss7_run(ftdm_thread_t * me, void *obj)
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)) {
@ -375,11 +375,11 @@ static void *ftdm_sangoma_ss7_run(ftdm_thread_t * me, void *obj)
} /* 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)) {
@ -396,7 +396,7 @@ static void *ftdm_sangoma_ss7_run(ftdm_thread_t * me, void *obj)
} /* 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);
@ -801,14 +801,14 @@ static void ftdm_sangoma_ss7_process_state_change (ftdm_channel_t * ftdmchan)
* 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 */
@ -822,6 +822,7 @@ static void ftdm_sangoma_ss7_process_state_change (ftdm_channel_t * ftdmchan)
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);
}
@ -1295,6 +1296,7 @@ static ftdm_status_t ftdm_sangoma_ss7_start(ftdm_span_t * span)
{
ftdm_channel_t *ftdmchan = NULL;
sngss7_chan_data_t *sngss7_info = NULL;
sngss7_span_data_t *sngss7_span = NULL;
int x;
@ -1305,6 +1307,7 @@ static ftdm_status_t ftdm_sangoma_ss7_start(ftdm_span_t * span)
/* 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);
@ -1316,6 +1319,8 @@ static ftdm_status_t ftdm_sangoma_ss7_start(ftdm_span_t * span)
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 */

View File

@ -346,7 +346,8 @@ typedef struct sngss7_chan_data {
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;

View File

@ -415,7 +415,7 @@ void ft_to_sngss7_gra (ftdm_channel_t * ftdmchan)
{
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;
@ -426,11 +426,11 @@ void ft_to_sngss7_gra (ftdm_channel_t * ftdmchan)
/* 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
@ -440,12 +440,14 @@ void ft_to_sngss7_gra (ftdm_channel_t * ftdmchan)
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;
@ -454,31 +456,32 @@ void ft_to_sngss7_gra (ftdm_channel_t * ftdmchan)
/******************************************************************************/
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;
}