freetdm: ss7 - enabled GRS instead of RSC, numerous bug fixes

This commit is contained in:
Konrad Hammel 2010-09-27 14:30:19 -04:00
parent 5a42adf40d
commit 4013fb510f
6 changed files with 159 additions and 24 deletions

View File

@ -1020,8 +1020,8 @@ int ftmod_ss7_mtp3_route_config(int id)
cfg.t.cfg.s.snRout.slsRange = LSN_ANSI_5BIT_SLS_RANGE; /* max value of SLS for this DPC */ cfg.t.cfg.s.snRout.slsRange = LSN_ANSI_5BIT_SLS_RANGE; /* max value of SLS for this DPC */
} }
cfg.t.cfg.s.snRout.lsetSel = 0x1; /* linkset selection bit in SLS for STP */ cfg.t.cfg.s.snRout.lsetSel = 0x1; /* linkset selection bit in SLS for STP */
cfg.t.cfg.s.snRout.multiMsgPrior = FALSE; /* TRUE if multiple cong priorities of messages */ cfg.t.cfg.s.snRout.multiMsgPrior = TRUE; /* TRUE if multiple cong priorities of messages */
cfg.t.cfg.s.snRout.rctReq = TRUE; /* route set congestion test required or not */ cfg.t.cfg.s.snRout.rctReq = TRUE; /* route set congestion test required or not */
cfg.t.cfg.s.snRout.slsLnk = FALSE; cfg.t.cfg.s.snRout.slsLnk = FALSE;
#ifdef LSNV2 #ifdef LSNV2
# if (SS7_NTT || defined(TDS_ROLL_UPGRADE_SUPPORT)) # if (SS7_NTT || defined(TDS_ROLL_UPGRADE_SUPPORT))

View File

@ -240,9 +240,7 @@ ftdm_status_t ftdm_sngss7_handle_cli_cmd(ftdm_stream_handle_t *stream, const cha
/**********************************************************************/ /**********************************************************************/
} else if (!strcasecmp(argv[c], "mem")) { } else if (!strcasecmp(argv[c], "mem")) {
/**********************************************************************/ /**********************************************************************/
/*uint32_t availMem;*/ sng_isup_reg_info_show();
/*sng_sta_mem(&availMem);*/
/**********************************************************************/ /**********************************************************************/
} else if (!strcasecmp(argv[c], "stats")) { } else if (!strcasecmp(argv[c], "stats")) {
/**********************************************************************/ /**********************************************************************/

View File

@ -73,6 +73,7 @@ ftdm_status_t handle_local_ubl(uint32_t suInstId, uint32_t spInstId, uint32_t ci
ftdm_status_t handle_ucic(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, uint8_t globalFlg, uint8_t evntType, SiStaEvnt *siStaEvnt); ftdm_status_t handle_ucic(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, uint8_t globalFlg, uint8_t evntType, SiStaEvnt *siStaEvnt);
ftdm_status_t handle_cgb_req(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, uint8_t globalFlg, uint8_t evntType, SiStaEvnt *siStaEvnt); ftdm_status_t handle_cgb_req(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, uint8_t globalFlg, uint8_t evntType, SiStaEvnt *siStaEvnt);
ftdm_status_t handle_cgu_req(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, uint8_t globalFlg, uint8_t evntType, SiStaEvnt *siStaEvnt); ftdm_status_t handle_cgu_req(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, uint8_t globalFlg, uint8_t evntType, SiStaEvnt *siStaEvnt);
ftdm_status_t handle_olm_msg(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, uint8_t globalFlg, uint8_t evntType, SiStaEvnt *siStaEvnt);
/******************************************************************************/ /******************************************************************************/
/* FUNCTIONS ******************************************************************/ /* FUNCTIONS ******************************************************************/
@ -928,7 +929,7 @@ ftdm_status_t handle_sta_ind(uint32_t suInstId, uint32_t spInstId, uint32_t circ
/**************************************************************************/ /**************************************************************************/
case SIT_STA_OVERLOAD: /* Overload */ case SIT_STA_OVERLOAD: /* Overload */
SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Rx Overload\n", sngss7_info->circuit->cic); 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)); handle_olm_msg(suInstId, spInstId, circuit, globalFlg, evntType, siStaEvnt);
break; break;
/**************************************************************************/ /**************************************************************************/
case SIT_STA_LMCGBREQ: /* when LM requests ckt grp blocking */ case SIT_STA_LMCGBREQ: /* when LM requests ckt grp blocking */
@ -1685,8 +1686,10 @@ ftdm_status_t handle_ucic(uint32_t suInstId, uint32_t spInstId, uint32_t circuit
{ {
SS7_FUNC_TRACE_ENTER(__FUNCTION__); SS7_FUNC_TRACE_ENTER(__FUNCTION__);
sngss7_chan_data_t *sngss7_info = NULL; sngss7_chan_data_t *sngss7_info = NULL;
ftdm_channel_t *ftdmchan = NULL; sngss7_span_data_t *sngss7_span = NULL;
ftdm_channel_t *ftdmchan = NULL;
/* get the ftdmchan and ss7_chan_data from the circuit */ /* get the ftdmchan and ss7_chan_data from the circuit */
if (extract_chan_data(circuit, &sngss7_info, &ftdmchan)) { if (extract_chan_data(circuit, &sngss7_info, &ftdmchan)) {
@ -1695,6 +1698,15 @@ ftdm_status_t handle_ucic(uint32_t suInstId, uint32_t spInstId, uint32_t circuit
return FTDM_FAIL; return FTDM_FAIL;
} }
/* check if we just sent a GRS request...*/
sngss7_span = ftdmchan->span->mod_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;
}
/* lock the channel */ /* lock the channel */
ftdm_mutex_lock(ftdmchan->mutex); ftdm_mutex_lock(ftdmchan->mutex);
@ -1706,7 +1718,7 @@ ftdm_status_t handle_ucic(uint32_t suInstId, uint32_t spInstId, uint32_t circuit
/* unlock the channel again before we exit */ /* unlock the channel again before we exit */
ftdm_mutex_unlock(ftdmchan->mutex); ftdm_mutex_unlock(ftdmchan->mutex);
done:
SS7_FUNC_TRACE_EXIT(__FUNCTION__); SS7_FUNC_TRACE_EXIT(__FUNCTION__);
return FTDM_SUCCESS; return FTDM_SUCCESS;
} }
@ -1983,6 +1995,30 @@ ftdm_status_t handle_cgu_req(uint32_t suInstId, uint32_t spInstId, uint32_t circ
return FTDM_SUCCESS; return FTDM_SUCCESS;
} }
/******************************************************************************/
ftdm_status_t handle_olm_msg(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, uint8_t globalFlg, uint8_t evntType, SiStaEvnt *siStaEvnt)
{
SS7_FUNC_TRACE_ENTER(__FUNCTION__);
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(circuit, &sngss7_info, &ftdmchan)) {
SS7_ERROR("Failed to extract channel data for circuit = %d!\n", circuit);
SS7_FUNC_TRACE_EXIT(__FUNCTION__);
return FTDM_FAIL;
}
/* handle overload */
SS7_ERROR_CHAN(ftdmchan,"[CIC:%d]Rx Overload\n", sngss7_info->circuit->cic);
sng_isup_reg_info_show();
SS7_FUNC_TRACE_EXIT(__FUNCTION__);
return FTDM_SUCCESS;
}
/******************************************************************************/ /******************************************************************************/
/* For Emacs: /* For Emacs:
* Local Variables: * Local Variables:

View File

@ -356,6 +356,12 @@ static void *ftdm_sangoma_ss7_run(ftdm_thread_t * me, void *obj)
check_if_rx_grs_processed(ftdmspan); check_if_rx_grs_processed(ftdmspan);
} /* if (sngss7_span->rx_grs.range > 0) */ } /* 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) {
/* 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 each channel on the span to see if there is an un-procressed SUS/RES flag */
check_for_res_sus_flag(ftdmspan); check_for_res_sus_flag(ftdmspan);
} /* master while loop */ } /* master while loop */
@ -592,6 +598,8 @@ void ftdm_sangoma_ss7_process_state_change (ftdm_channel_t * ftdmchan)
} else { } else {
/* inbound call so we need to send out ACM */ /* inbound call so we need to send out ACM */
ft_to_sngss7_acm (ftdmchan); ft_to_sngss7_acm (ftdmchan);
ftdm_set_state_locked (ftdmchan, FTDM_CHANNEL_STATE_PROGRESS_MEDIA);
} }
break; break;
@ -763,9 +771,7 @@ void ftdm_sangoma_ss7_process_state_change (ftdm_channel_t * ftdmchan)
ft_to_sngss7_gra(ftdmchan); ft_to_sngss7_gra(ftdmchan);
/* clean out the spans GRS structure */ /* clean out the spans GRS structure */
sngss7_span_data_t *span = ftdmchan->span->mod_data; clear_rx_grs_data(sngss7_info);
span->rx_grs.circuit = 0;
span->rx_grs.range = 0;
} }
/* clear the grp reset flag */ /* clear the grp reset flag */
@ -783,9 +789,7 @@ void ftdm_sangoma_ss7_process_state_change (ftdm_channel_t * ftdmchan)
clear_tx_grs_flags(sngss7_info); clear_tx_grs_flags(sngss7_info);
/* clean out the spans GRA structure */ /* clean out the spans GRA structure */
sngss7_span_data_t *span = ftdmchan->span->mod_data; clear_rx_gra_data(sngss7_info);
span->rx_gra.circuit = 0;
span->rx_gra.range = 0;
} /* if (sngss7_test_flag(sngss7_info, FLAG_GRP_RESET_TX_RSP)) */ } /* if (sngss7_test_flag(sngss7_info, FLAG_GRP_RESET_TX_RSP)) */
/* check if we came from reset (aka we just processed a reset) */ /* check if we came from reset (aka we just processed a reset) */
@ -877,6 +881,11 @@ void ftdm_sangoma_ss7_process_state_change (ftdm_channel_t * ftdmchan)
/* set the unblk flag */ /* set the unblk flag */
sngss7_set_flag(sngss7_info, FLAG_CKT_UCIC_UNBLK); sngss7_set_flag(sngss7_info, FLAG_CKT_UCIC_UNBLK);
/* clear the block flag */
sngss7_clear_flag(sngss7_info, FLAG_CKT_UCIC_BLOCK);
/* process the flag */
ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_SUSPENDED); ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_SUSPENDED);
/* break out of the processing for now */ /* break out of the processing for now */
@ -1112,7 +1121,9 @@ void ftdm_sangoma_ss7_process_state_change (ftdm_channel_t * ftdmchan)
/* remove any reset flags */ /* remove any reset flags */
clear_rx_grs_flags(sngss7_info); clear_rx_grs_flags(sngss7_info);
clear_rx_grs_data(sngss7_info);
clear_tx_grs_flags(sngss7_info); clear_tx_grs_flags(sngss7_info);
clear_tx_grs_data(sngss7_info);
clear_rx_rsc_flags(sngss7_info); clear_rx_rsc_flags(sngss7_info);
clear_tx_rsc_flags(sngss7_info); clear_tx_rsc_flags(sngss7_info);
@ -1321,7 +1332,7 @@ static ftdm_status_t ftdm_sangoma_ss7_start(ftdm_span_t * span)
sngss7_clear_flag(sngss7_info, FLAG_INFID_PAUSED); sngss7_clear_flag(sngss7_info, FLAG_INFID_PAUSED);
sngss7_set_flag(sngss7_info, FLAG_INFID_RESUME); sngss7_set_flag(sngss7_info, FLAG_INFID_RESUME);
} }
#if 0 #if 1
/* throw the grp reset flag */ /* throw the grp reset flag */
sngss7_set_flag(sngss7_info, FLAG_GRP_RESET_TX); sngss7_set_flag(sngss7_info, FLAG_GRP_RESET_TX);
if (x == 1) { if (x == 1) {

View File

@ -361,6 +361,7 @@ typedef struct sngss7_span_data {
sngss7_group_data_t tx_cgb; sngss7_group_data_t tx_cgb;
sngss7_group_data_t rx_cgu; sngss7_group_data_t rx_cgu;
sngss7_group_data_t tx_cgu; sngss7_group_data_t tx_cgu;
sngss7_group_data_t ucic;
ftdm_queue_t *event_queue; ftdm_queue_t *event_queue;
}sngss7_span_data_t; }sngss7_span_data_t;
@ -566,10 +567,15 @@ ftdm_status_t check_if_rx_grs_processed(ftdm_span_t *ftdmspan);
ftdm_status_t check_if_rx_gra_started(ftdm_span_t *ftdmspan); ftdm_status_t check_if_rx_gra_started(ftdm_span_t *ftdmspan);
ftdm_status_t check_for_res_sus_flag(ftdm_span_t *ftdmspan); 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_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_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_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_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);
/* in ftmod_sangoma_ss7_timers.c */ /* in ftmod_sangoma_ss7_timers.c */

View File

@ -62,10 +62,15 @@ ftdm_status_t check_if_rx_grs_processed(ftdm_span_t *ftdmspan);
ftdm_status_t check_if_rx_gra_started(ftdm_span_t *ftdmspan); ftdm_status_t check_if_rx_gra_started(ftdm_span_t *ftdmspan);
ftdm_status_t check_for_res_sus_flag(ftdm_span_t *ftdmspan); 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_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_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_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_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);
/******************************************************************************/ /******************************************************************************/
/* FUNCTIONS ******************************************************************/ /* FUNCTIONS ******************************************************************/
@ -159,8 +164,8 @@ uint8_t copy_cgPtyNum_to_sngss7(ftdm_caller_data_t *ftdm, SiCgPtyNum *cgPtyNum)
} else { } else {
/* keep the odd flag down */ /* keep the odd flag down */
odd = 0; odd = 0;
/* throw the flag */ /* break right away since we don't need to write the digits */
flag = 1; break;
} }
/* push the digits into the trillium structure */ /* push the digits into the trillium structure */
@ -261,14 +266,14 @@ uint8_t copy_cdPtyNum_to_sngss7(ftdm_caller_data_t *ftdm, SiCdPtyNum *cdPtyNum)
upper = (atoi(&tmp[0])) << 4; upper = (atoi(&tmp[0])) << 4;
} else { } else {
/* there is no upper ... fill in ST */ /* there is no upper ... fill in ST */
upper = 0xF; upper = 0xF0;
/* throw the odd flag */ /* keep the odd flag down */
odd = 1; odd = 0;
/* throw the end flag */ /* throw the end flag */
flag = 1; flag = 1;
} /* if (tmp != '\0') */ } /* if (tmp != '\0') */
} else { } else {
/* keep the odd flag down */ /* throw the odd flag */
odd = 1; odd = 1;
/* need to add the ST */ /* need to add the ST */
lower = 0xF; lower = 0xF;
@ -525,7 +530,7 @@ ftdm_status_t check_if_rx_grs_processed(ftdm_span_t *ftdmspan)
int bit = 0; int bit = 0;
ftdm_log(FTDM_LOG_DEBUG, "Found Rx GRS on span %d...checking circuits\n", ftdmspan->span_id); ftdm_log(FTDM_LOG_DEBUG, "Found Rx GRS on span %s...checking circuits\n", ftdmspan->name);
/* check all the circuits in the range to see if they are done resetting */ /* 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++) { for ( i = sngss7_span->rx_grs.circuit; i < (sngss7_span->rx_grs.circuit + sngss7_span->rx_grs.range + 1); i++) {
@ -614,7 +619,7 @@ ftdm_status_t check_if_rx_gra_started(ftdm_span_t *ftdmspan)
sngss7_span_data_t *sngss7_span = (sngss7_span_data_t *)ftdmspan->mod_data; sngss7_span_data_t *sngss7_span = (sngss7_span_data_t *)ftdmspan->mod_data;
int i; int i;
for ( i = sngss7_span->rx_gra.circuit; i < (sngss7_span->rx_gra.circuit + sngss7_span->rx_gra.range + 1); i++) { for (i = sngss7_span->rx_gra.circuit; i < (sngss7_span->rx_gra.circuit + sngss7_span->rx_gra.range + 1); i++) {
/* extract the channel in question */ /* extract the channel in question */
if (extract_chan_data(i, &sngss7_info, &ftdmchan)) { if (extract_chan_data(i, &sngss7_info, &ftdmchan)) {
@ -756,6 +761,48 @@ ftdm_status_t check_for_res_sus_flag(ftdm_span_t *ftdmspan)
return FTDM_SUCCESS; return FTDM_SUCCESS;
} }
/******************************************************************************/
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->mod_data;
int i;
for (i = sngss7_span->ucic.circuit; i < (sngss7_span->ucic.circuit + sngss7_span->ucic.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;
}
/* lock the channel */
ftdm_mutex_lock(ftdmchan->mutex);
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_flag(sngss7_info, FLAG_CKT_UCIC_BLOCK);
/* set the channel to suspended state */
ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_SUSPENDED);
/* unlock the channel again before we exit */
ftdm_mutex_unlock(ftdmchan->mutex);
}
/* clear out the ucic data since we're done with it */
memset(&sngss7_span->ucic, 0x0, sizeof(sngss7_group_data_t));
return FTDM_SUCCESS;
}
/******************************************************************************/ /******************************************************************************/
ftdm_status_t clear_rx_grs_flags(sngss7_chan_data_t *sngss7_info) ftdm_status_t clear_rx_grs_flags(sngss7_chan_data_t *sngss7_info)
{ {
@ -767,6 +814,29 @@ ftdm_status_t clear_rx_grs_flags(sngss7_chan_data_t *sngss7_info)
return FTDM_SUCCESS; return FTDM_SUCCESS;
} }
/******************************************************************************/
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->mod_data;
/* clear the rx_grs data fields */
memset(&sngss7_span->rx_grs, 0x0, sizeof(sngss7_group_data_t));
return FTDM_SUCCESS;
}
/******************************************************************************/
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->mod_data;
/* clear the rx_grs data fields */
memset(&sngss7_span->rx_gra, 0x0, sizeof(sngss7_group_data_t));
return FTDM_SUCCESS;
}
/******************************************************************************/ /******************************************************************************/
ftdm_status_t clear_tx_grs_flags(sngss7_chan_data_t *sngss7_info) ftdm_status_t clear_tx_grs_flags(sngss7_chan_data_t *sngss7_info)
{ {
@ -779,6 +849,20 @@ ftdm_status_t clear_tx_grs_flags(sngss7_chan_data_t *sngss7_info)
return FTDM_SUCCESS; return FTDM_SUCCESS;
} }
/******************************************************************************/
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->mod_data;
/* clear the rx_grs data fields */
memset(&sngss7_span->tx_grs, 0x0, sizeof(sngss7_group_data_t));
return FTDM_SUCCESS;
}
/******************************************************************************/
/******************************************************************************/ /******************************************************************************/
ftdm_status_t clear_rx_rsc_flags(sngss7_chan_data_t *sngss7_info) ftdm_status_t clear_rx_rsc_flags(sngss7_chan_data_t *sngss7_info)
{ {