ftdm_status_t handle_fac_ind(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, uint8_t evntType, SiFacEvnt *siFacEvnt);
ftdm_status_t handle_fac_cfm(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, uint8_t evntType, SiFacEvnt *siFacEvnt);
ftdm_status_t handle_umsg_ind(uint32_t suInstId, uint32_t spInstId, uint32_t circuit);
+ftdm_status_t handle_susp_ind(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, SiSuspEvnt *siSuspEvnt);
+ftdm_status_t handle_resm_ind(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, SiResmEvnt *siResmEvnt);
ftdm_status_t handle_sta_ind(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, uint8_t globalFlg, uint8_t evntType, SiStaEvnt *siStaEvnt);
ftdm_status_t handle_reattempt(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, uint8_t globalFlg, uint8_t evntType, SiStaEvnt *siStaEvnt);
/* need to grab the sp instance id */
sngss7_info->spInstId = spInstId;
- /* go to PROGRESS */
- ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_PROGRESS);
+ if ((siCnStEvnt->optBckCalInd.eh.pres) &&
+ (siCnStEvnt->optBckCalInd.inbndInfoInd.pres)) {
+
+ if (siCnStEvnt->optBckCalInd.inbndInfoInd.val) {
+ /* go to PROGRESS_MEDIA */
+ ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_PROGRESS_MEDIA);
+ } else {
+ /* go to PROGRESS */
+ ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_PROGRESS);
+ } /* if (inband) */
+ } else {
+ /* go to PROGRESS_MEDIA */
+ ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_PROGRESS_MEDIA);
+ }
+
break;
/**********************************************************************/
default: /* incorrect state...reset the CIC */
return FTDM_SUCCESS;
}
+/******************************************************************************/
+ftdm_status_t handle_susp_ind(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, SiSuspEvnt *siSuspEvnt)
+{
+ SS7_FUNC_TRACE_ENTER(__FUNCTION__);
+
+ sngss7_chan_data_t *sngss7_info ;
+ ftdm_channel_t *ftdmchan;
+
+ /* 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;
+ }
+
+ /* lock the channel */
+ ftdm_mutex_lock(ftdmchan->mutex);
+
+ SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Rx Call-Suspend msg\n", sngss7_info->circuit->cic);
+
+ /* unlock the channel */
+ ftdm_mutex_unlock(ftdmchan->mutex);
+
+ SS7_FUNC_TRACE_EXIT(__FUNCTION__);
+ return FTDM_SUCCESS;
+}
+
+/******************************************************************************/
+ftdm_status_t handle_resm_ind(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, SiResmEvnt *siResmEvnt)
+{
+ SS7_FUNC_TRACE_ENTER(__FUNCTION__);
+
+ sngss7_chan_data_t *sngss7_info ;
+ ftdm_channel_t *ftdmchan;
+
+ /* 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;
+ }
+
+ /* lock the channel */
+ ftdm_mutex_lock(ftdmchan->mutex);
+
+ SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Rx Call-Resume msg\n", sngss7_info->circuit->cic);
+
+ /* unlock the channel */
+ ftdm_mutex_unlock(ftdmchan->mutex);
+
+ SS7_FUNC_TRACE_EXIT(__FUNCTION__);
+ return FTDM_SUCCESS;
+}
+
/******************************************************************************/
ftdm_status_t handle_sta_ind(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, uint8_t globalFlg, uint8_t evntType, SiStaEvnt *siStaEvnt)
{
void sngss7_fac_ind(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, uint8_t evntType, SiFacEvnt *siFacEvnt);
void sngss7_fac_cfm(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, uint8_t evntType, SiFacEvnt *siFacEvnt);
void sngss7_umsg_ind(uint32_t suInstId, uint32_t spInstId, uint32_t circuit);
-
+void sngss7_resm_ind(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, SiResmEvnt *siResmEvnt);
+void sngss7_susp_ind(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, SiSuspEvnt *siSuspEvnt);
+void sngss7_ssp_sta_cfm(uint32_t infId);
/******************************************************************************/
/* FUNCTIONS ******************************************************************/
}
/******************************************************************************/
+void sngss7_susp_ind(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, SiSuspEvnt *siSuspEvnt)
+{
+ SS7_FUNC_TRACE_ENTER(__FUNCTION__);
+
+ sngss7_chan_data_t *sngss7_info = NULL;
+ ftdm_channel_t *ftdmchan = NULL;
+ sngss7_event_data_t *sngss7_event = 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;
+ }
+
+ /* initalize the sngss7_event */
+ sngss7_event = ftdm_malloc(sizeof(*sngss7_event));
+ if (sngss7_event == NULL) {
+ SS7_ERROR("Failed to allocate memory for sngss7_event!\n");
+ SS7_FUNC_TRACE_EXIT(__FUNCTION__);
+ return;
+ }
+ memset(sngss7_event, 0x0, sizeof(*sngss7_event));
+
+ /* fill in the sngss7_event struct */
+ sngss7_event->spInstId = spInstId;
+ sngss7_event->suInstId = suInstId;
+ sngss7_event->circuit = circuit;
+ sngss7_event->event_id = SNGSS7_SUSP_IND_EVENT;
+ if (siSuspEvnt != NULL) {
+ memcpy(&sngss7_event->event.siSuspEvnt, siSuspEvnt, sizeof(*siSuspEvnt));
+ }
+
+ /* enqueue this event */
+ ftdm_queue_enqueue(((sngss7_span_data_t*)sngss7_info->ftdmchan->span->mod_data)->event_queue, sngss7_event);
+
+ SS7_FUNC_TRACE_EXIT(__FUNCTION__);
+
+}
+
+/******************************************************************************/
+void sngss7_resm_ind(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, SiResmEvnt *siResmEvnt)
+{
+ SS7_FUNC_TRACE_ENTER(__FUNCTION__);
+ sngss7_chan_data_t *sngss7_info = NULL;
+ ftdm_channel_t *ftdmchan = NULL;
+ sngss7_event_data_t *sngss7_event = 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;
+ }
+
+ /* initalize the sngss7_event */
+ sngss7_event = ftdm_malloc(sizeof(*sngss7_event));
+ if (sngss7_event == NULL) {
+ SS7_ERROR("Failed to allocate memory for sngss7_event!\n");
+ SS7_FUNC_TRACE_EXIT(__FUNCTION__);
+ return;
+ }
+ memset(sngss7_event, 0x0, sizeof(*sngss7_event));
+
+ /* fill in the sngss7_event struct */
+ sngss7_event->spInstId = spInstId;
+ sngss7_event->suInstId = suInstId;
+ sngss7_event->circuit = circuit;
+ sngss7_event->event_id = SNGSS7_RESM_IND_EVENT;
+ if (siResmEvnt != NULL) {
+ memcpy(&sngss7_event->event.siResmEvnt, siResmEvnt, sizeof(*siResmEvnt));
+ }
+
+ /* enqueue this event */
+ ftdm_queue_enqueue(((sngss7_span_data_t*)sngss7_info->ftdmchan->span->mod_data)->event_queue, sngss7_event);
+
+ SS7_FUNC_TRACE_EXIT(__FUNCTION__);
+
+}
+
+/******************************************************************************/
+void sngss7_ssp_sta_cfm(uint32_t infId)
+{
+ SS7_FUNC_TRACE_ENTER(__FUNCTION__);
+#if 0
+ sngss7_chan_data_t *sngss7_info = NULL;
+ ftdm_channel_t *ftdmchan = NULL;
+ sngss7_event_data_t *sngss7_event = 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;
+ }
+
+ /* initalize the sngss7_event */
+ sngss7_event = ftdm_malloc(sizeof(*sngss7_event));
+ if (sngss7_event == NULL) {
+ SS7_ERROR("Failed to allocate memory for sngss7_event!\n");
+ SS7_FUNC_TRACE_EXIT(__FUNCTION__);
+ return;
+ }
+ memset(sngss7_event, 0x0, sizeof(*sngss7_event));
+
+ /* fill in the sngss7_event struct */
+ sngss7_event->spInstId = spInstId;
+ sngss7_event->suInstId = suInstId;
+ sngss7_event->circuit = circuit;
+ sngss7_event->event_id = SNGSS7_RESM_IND_EVENT;
+ if (siSuspEvnt != NULL) {
+ memcpy(&sngss7_event->event.siResmEvnt, siResmEvnt, sizeof(*siResmEvnt));
+ }
+
+ /* enqueue this event */
+ ftdm_queue_enqueue(((sngss7_span_data_t*)sngss7_info->ftdmchan->span->mod_data)->event_queue, sngss7_event);
+#endif
+ SS7_FUNC_TRACE_EXIT(__FUNCTION__);
+
+}
/******************************************************************************/
/* For Emacs:
* Local Variables:
{FTDM_CHANNEL_STATE_SUSPENDED, FTDM_CHANNEL_STATE_RESTART,
FTDM_CHANNEL_STATE_CANCEL, FTDM_CHANNEL_STATE_TERMINATING,
FTDM_CHANNEL_STATE_HANGUP, FTDM_CHANNEL_STATE_PROGRESS,
- FTDM_CHANNEL_STATE_UP, FTDM_END}
+ FTDM_CHANNEL_STATE_PROGRESS_MEDIA ,FTDM_CHANNEL_STATE_UP, FTDM_END}
},
{
ZSD_OUTBOUND,
handle_sta_ind(sngss7_event->suInstId, sngss7_event->spInstId, sngss7_event->circuit, sngss7_event->globalFlg, sngss7_event->evntType, &sngss7_event->event.siStaEvnt);
break;
/**************************************************************************/
+ case (SNGSS7_SUSP_IND_EVENT):
+ handle_susp_ind(sngss7_event->suInstId, sngss7_event->spInstId, sngss7_event->circuit, &sngss7_event->event.siSuspEvnt);
+ break;
+ /**************************************************************************/
+ case (SNGSS7_RESM_IND_EVENT):
+ handle_resm_ind(sngss7_event->suInstId, sngss7_event->spInstId, sngss7_event->circuit, &sngss7_event->event.siResmEvnt);
+ break;
+ /**************************************************************************/
+ case (SNGSS7_SSP_STA_CFM_EVENT):
+ break;
+ /**************************************************************************/
default:
SS7_ERROR("Unknown Event Id!\n");
break;
void 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 i = 0;
ftdm_sigmsg_t sigev;
}
/*check if the channel is inbound or outbound */
- if (ftdm_test_flag (ftdmchan, FTDM_CHANNEL_OUTBOUND)) {
+ if (ftdm_test_flag (ftdmchan, FTDM_CHANNEL_OUTBOUND)) {
/*OUTBOUND...so we were told by the line of this so noifiy the user */
sigev.event_id = FTDM_SIGEVENT_PROGRESS;
ftdm_span_send_signal (ftdmchan->span, &sigev);
+ /* move to progress media */
ftdm_set_state_locked (ftdmchan, FTDM_CHANNEL_STATE_PROGRESS_MEDIA);
} else {
/* inbound call so we need to send out ACM */
- ft_to_sngss7_acm (ftdmchan);
-
- ftdm_set_state_locked (ftdmchan, FTDM_CHANNEL_STATE_PROGRESS_MEDIA);
+ ft_to_sngss7_acm(ftdmchan);
}
break;
break;
}
+ if (ftdm_test_flag (ftdmchan, FTDM_CHANNEL_OUTBOUND)) {
+ /* inform the user there is media avai */
+ sigev.event_id = FTDM_SIGEVENT_PROGRESS_MEDIA;
+ ftdm_span_send_signal (ftdmchan->span, &sigev);
+ }
+
+
/* nothing to do at this time */
break;
/**************************************************************************/
ftdm_set_state_locked (ftdmchan, FTDM_CHANNEL_STATE_RESTART);
break;
-/**************************************************************************/
+ /**************************************************************************/
case FTDM_CHANNEL_STATE_IN_LOOP: /* COT test */
- /* send the lpa */
- ft_to_sngss7_lpa (ftdmchan);
+ isup_intf = &g_ftdm_sngss7_data.cfg.isupIntf[sngss7_info->circuit->infId];
+
+ if (sngss7_test_options(isup_intf, SNGSS7_LPA_FOR_COT)) {
+ /* send the lpa */
+ ft_to_sngss7_lpa (ftdmchan);
+ }
break;
/**************************************************************************/
sng_event.cc.sng_fac_cfm = sngss7_fac_cfm;
sng_event.cc.sng_sta_ind = sngss7_sta_ind;
sng_event.cc.sng_umsg_ind = sngss7_umsg_ind;
- sng_event.cc.sng_susp_ind = NULL;
- sng_event.cc.sng_resm_ind = NULL;
- sng_event.cc.sng_ssp_sta_cfm = NULL;
+ sng_event.cc.sng_susp_ind = sngss7_susp_ind;
+ sng_event.cc.sng_resm_ind = sngss7_resm_ind;
+ sng_event.cc.sng_ssp_sta_cfm = sngss7_ssp_sta_cfm;
sng_event.sm.sng_log = handle_sng_log;
sng_event.sm.sng_mtp1_alarm = handle_sng_mtp1_alarm;
SNGSS7_FAC_IND_EVENT,
SNGSS7_FAC_CFM_EVENT,
SNGSS7_UMSG_IND_EVENT,
- SNGSS7_STA_IND_EVENT
+ SNGSS7_STA_IND_EVENT,
+ SNGSS7_SUSP_IND_EVENT,
+ SNGSS7_RESM_IND_EVENT,
+ SNGSS7_SSP_STA_CFM_EVENT
} sng_event_type_t;
typedef enum {
} sng_flag_t;
typedef enum {
- SNGSS7_ACM_OBCI_BITA = (1 << 0) /* in-band indication */
+ SNGSS7_LPA_FOR_COT = (1 << 0), /* send LPA when COT arrives */
+ SNGSS7_ACM_OBCI_BITA = (1 << 10) /* in-band indication */
} sng_intf_options_t;
typedef enum {
SiInfoEvnt siInfoEvnt;
SiFacEvnt siFacEvnt;
SiStaEvnt siStaEvnt;
+ SiSuspEvnt siSuspEvnt;
+ SiResmEvnt siResmEvnt;
} event;
} sngss7_event_data_t;
void sngss7_fac_cfm(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, uint8_t evntType, SiFacEvnt *siFacEvnt);
void sngss7_sta_ind(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, uint8_t globalFlg, uint8_t evntType, SiStaEvnt *siStaEvnt);
void sngss7_umsg_ind(uint32_t suInstId, uint32_t spInstId, uint32_t circuit);
+void sngss7_resm_ind(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, SiResmEvnt *siResmEvnt);
+void sngss7_susp_ind(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, SiSuspEvnt *siSuspEvnt);
+void sngss7_ssp_sta_cfm(uint32_t infId);
/* in ftmod_sangoma_ss7_handle.c */
ftdm_status_t handle_con_ind(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, SiConEvnt *siConEvnt);
ftdm_status_t handle_fac_ind(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, uint8_t evntType, SiFacEvnt *siFacEvnt);
ftdm_status_t handle_fac_cfm(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, uint8_t evntType, SiFacEvnt *siFacEvnt);
ftdm_status_t handle_umsg_ind(uint32_t suInstId, uint32_t spInstId, uint32_t circuit);
+ftdm_status_t handle_susp_ind(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, SiSuspEvnt *siSuspEvnt);
+ftdm_status_t handle_resm_ind(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, SiResmEvnt *siResmEvnt);
ftdm_status_t handle_sta_ind(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, uint8_t globalFlg, uint8_t evntType, SiStaEvnt *siStaEvnt);
ftdm_status_t handle_reattempt(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, uint8_t globalFlg, uint8_t evntType, SiStaEvnt *siStaEvnt);
SS7_DEBUG("\tInvalid value for \"obci_bita\" option\n");
}
/**********************************************************************/
+ } else if (!strcasecmp(parm->var, "lpa_on_cot")) {
+ /**********************************************************************/
+ if (*parm->val == '1') {
+ sngss7_set_options(&sng_isup, SNGSS7_LPA_FOR_COT);
+ SS7_DEBUG("\tFound Tx LPA on COT enable option\n");
+ } else if (*parm->val == '0') {
+ sngss7_clear_options(&sng_isup, SNGSS7_LPA_FOR_COT);
+ SS7_DEBUG("\tFound Tx LPA on COT disable option\n");
+ } else {
+ SS7_DEBUG("\tInvalid value for \"lpa_on_cot\" option\n");
+ }
+ /**********************************************************************/
} else {
SS7_ERROR("\tFound an invalid parameter \"%s\"!\n", parm->val);
return FTDM_FAIL;