freetdm: INR/INF implementation
- When NSG receives INR from network, send back INF with calling party category information IE and calling number information IE. - Introduced a new global setting of "force-inr" for testing purpose. Stinga generated INR/INF packets are not acceptable by trillium stack since it misses call related information in the packets. If configure force-inr to true in freetdm.conf.xml, when NSG receives an incoming IAM, it'll send out INR packet regardless of incoming IAM's IEs, and keep waiting for INF response from the calling side. - T.39 timer is introduced in order to handle INR timeout. The default value of T.39 is 12 seconds and is configurable according to spec. - Only supports calling number IE and calling party category IE in current fix. The customer only needs the calling number IE right now. In ISUP spec, there are 6 optional IEs. NSG only supports calling party number and calling category information IE since the other IEs are not configurable in freetdm.conf.xml or included in IAM message. - In collect state, INR/INF implementation needs to work with existed SAM messages. If NSG sent out INR and wait for SAM, collect state check both INF received and enough dialed numbers received. If one of these conditions are not met, it'll stay in collect state and wait until either conditions met or timeout. After received INF and enough dailed number, state moves to dailing and proceed as regular calls.
This commit is contained in:
parent
7155001c86
commit
16d4f1f063
|
@ -132,6 +132,16 @@ ftdm_status_t handle_con_ind(uint32_t suInstId, uint32_t spInstId, uint32_t circ
|
|||
/* KONRAD FIX ME : check in case there is a ckt and grp block */
|
||||
}
|
||||
|
||||
sngss7_clear_ckt_flag(sngss7_info, FLAG_INR_TX);
|
||||
sngss7_clear_ckt_flag(sngss7_info, FLAG_INR_SENT);
|
||||
sngss7_clear_ckt_flag(sngss7_info, FLAG_INR_RX);
|
||||
sngss7_clear_ckt_flag(sngss7_info, FLAG_INR_RX_DN);
|
||||
sngss7_clear_ckt_flag(sngss7_info, FLAG_INF_TX);
|
||||
sngss7_clear_ckt_flag(sngss7_info, FLAG_INF_SENT);
|
||||
sngss7_clear_ckt_flag(sngss7_info, FLAG_INF_RX);
|
||||
sngss7_clear_ckt_flag(sngss7_info, FLAG_INF_RX_DN);
|
||||
sngss7_clear_ckt_flag(sngss7_info, FLAG_FULL_NUMBER);
|
||||
|
||||
/* check whether the ftdm channel is in a state to accept a call */
|
||||
switch (ftdmchan->state) {
|
||||
/**************************************************************************/
|
||||
|
@ -175,6 +185,12 @@ ftdm_status_t handle_con_ind(uint32_t suInstId, uint32_t spInstId, uint32_t circ
|
|||
/* fill in ANI */
|
||||
ftdm_set_string(ftdmchan->caller_data.ani.digits, ftdmchan->caller_data.cid_num.digits);
|
||||
}
|
||||
else {
|
||||
if (g_ftdm_sngss7_data.cfg.force_inr) {
|
||||
sngss7_set_ckt_flag(sngss7_info, FLAG_INR_TX);
|
||||
sngss7_clear_ckt_flag(sngss7_info, FLAG_INR_SENT);
|
||||
}
|
||||
}
|
||||
|
||||
if (siConEvnt->cgPtyNum.scrnInd.pres) {
|
||||
/* fill in the screening indication value */
|
||||
|
@ -186,6 +202,11 @@ ftdm_status_t handle_con_ind(uint32_t suInstId, uint32_t spInstId, uint32_t circ
|
|||
ftdmchan->caller_data.pres = siConEvnt->cgPtyNum.presRest.val;
|
||||
}
|
||||
} else {
|
||||
if (g_ftdm_sngss7_data.cfg.force_inr) {
|
||||
sngss7_set_ckt_flag(sngss7_info, FLAG_INR_TX);
|
||||
sngss7_clear_ckt_flag(sngss7_info, FLAG_INR_SENT);
|
||||
}
|
||||
|
||||
SS7_INFO_CHAN(ftdmchan,"No Calling party (ANI) information in IAM!%s\n", " ");
|
||||
}
|
||||
|
||||
|
@ -437,10 +458,26 @@ ftdm_status_t handle_con_sta(uint32_t suInstId, uint32_t spInstId, uint32_t circ
|
|||
/**************************************************************************/
|
||||
case (INFORMATION):
|
||||
SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Rx INF\n", sngss7_info->circuit->cic);
|
||||
|
||||
SS7_DEBUG_CHAN (ftdmchan, "Cancelling T.39 timer %s\n", " ");
|
||||
/* check if t39 is active */
|
||||
if (sngss7_info->t39.hb_timer_id) {
|
||||
ftdm_sched_cancel_timer (sngss7_info->t39.sched, sngss7_info->t39.hb_timer_id);
|
||||
SS7_DEBUG_CHAN (ftdmchan, "T.39 timer has been cancelled upon receiving INF message %s\n", " ");
|
||||
}
|
||||
|
||||
sngss7_set_ckt_flag(sngss7_info, FLAG_INF_RX_DN);
|
||||
ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_IDLE);
|
||||
|
||||
break;
|
||||
/**************************************************************************/
|
||||
case (INFORMATREQ):
|
||||
SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Rx INR\n", sngss7_info->circuit->cic);
|
||||
|
||||
ft_to_sngss7_inf(ftdmchan);
|
||||
|
||||
sngss7_set_ckt_flag(sngss7_info, FLAG_INR_RX);
|
||||
|
||||
break;
|
||||
/**************************************************************************/
|
||||
case (SUBSADDR):
|
||||
|
|
|
@ -1080,23 +1080,91 @@ ftdm_status_t ftdm_sangoma_ss7_process_state_change (ftdm_channel_t *ftdmchan)
|
|||
}
|
||||
|
||||
/* check if the end of pulsing (ST) character has arrived or the right number of digits */
|
||||
if (ftdmchan->caller_data.dnis.digits[i-1] == 'F') {
|
||||
if (ftdmchan->caller_data.dnis.digits[i-1] == 'F'
|
||||
|| sngss7_test_ckt_flag(sngss7_info, FLAG_FULL_NUMBER) )
|
||||
{
|
||||
SS7_DEBUG_CHAN(ftdmchan, "Received the end of pulsing character %s\n", "");
|
||||
|
||||
if (!sngss7_test_ckt_flag(sngss7_info, FLAG_FULL_NUMBER)) {
|
||||
/* remove the ST */
|
||||
ftdmchan->caller_data.dnis.digits[i-1] = '\0';
|
||||
sngss7_set_ckt_flag(sngss7_info, FLAG_FULL_NUMBER);
|
||||
}
|
||||
|
||||
/*now go to the RING state */
|
||||
if (sngss7_test_ckt_flag(sngss7_info, FLAG_INR_TX)) {
|
||||
if (!sngss7_test_ckt_flag(sngss7_info, FLAG_INR_SENT) ) {
|
||||
ft_to_sngss7_inr(ftdmchan);
|
||||
sngss7_set_ckt_flag(sngss7_info, FLAG_INR_SENT);
|
||||
|
||||
SS7_DEBUG_CHAN (ftdmchan, "Scheduling T.39 timer %s \n", " ");
|
||||
|
||||
/* start ISUP t39 */
|
||||
if (ftdm_sched_timer (sngss7_info->t39.sched,
|
||||
"t39",
|
||||
sngss7_info->t39.beat,
|
||||
sngss7_info->t39.callback,
|
||||
&sngss7_info->t39,
|
||||
&sngss7_info->t39.hb_timer_id))
|
||||
{
|
||||
|
||||
SS7_ERROR ("Unable to schedule timer T39, hanging up call!\n");
|
||||
|
||||
ftdmchan->caller_data.hangup_cause = FTDM_CAUSE_NORMAL_TEMPORARY_FAILURE;
|
||||
sngss7_set_ckt_flag (sngss7_info, FLAG_LOCAL_REL);
|
||||
|
||||
/* end the call */
|
||||
state_flag = 0;
|
||||
ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_CANCEL);
|
||||
}
|
||||
}else {
|
||||
state_flag = 0;
|
||||
ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_RING);
|
||||
|
||||
}
|
||||
} else {
|
||||
state_flag = 0;
|
||||
ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_RING);
|
||||
}
|
||||
} else if (i >= sngss7_info->circuit->min_digits) {
|
||||
SS7_DEBUG_CHAN(ftdmchan, "Received %d digits (min digits = %d)\n", i, sngss7_info->circuit->min_digits);
|
||||
|
||||
/*now go to the RING state */
|
||||
if (sngss7_test_ckt_flag(sngss7_info, FLAG_INR_TX)) {
|
||||
if (!sngss7_test_ckt_flag(sngss7_info, FLAG_INR_SENT) ) {
|
||||
ft_to_sngss7_inr(ftdmchan);
|
||||
sngss7_set_ckt_flag(sngss7_info, FLAG_INR_SENT);
|
||||
|
||||
SS7_DEBUG_CHAN (ftdmchan, "Scheduling T.39 timer %s\n", " " );
|
||||
|
||||
/* start ISUP t39 */
|
||||
if (ftdm_sched_timer (sngss7_info->t39.sched,
|
||||
"t39",
|
||||
sngss7_info->t39.beat,
|
||||
sngss7_info->t39.callback,
|
||||
&sngss7_info->t39,
|
||||
&sngss7_info->t39.hb_timer_id))
|
||||
{
|
||||
|
||||
SS7_ERROR ("Unable to schedule timer T39, hanging up call!\n");
|
||||
|
||||
ftdmchan->caller_data.hangup_cause = FTDM_CAUSE_NORMAL_TEMPORARY_FAILURE;
|
||||
sngss7_set_ckt_flag (sngss7_info, FLAG_LOCAL_REL);
|
||||
|
||||
/* end the call */
|
||||
state_flag = 0;
|
||||
ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_CANCEL);
|
||||
}
|
||||
|
||||
state_flag = 0;
|
||||
ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_IDLE);
|
||||
}else {
|
||||
if (sngss7_test_ckt_flag(sngss7_info, FLAG_INF_RX_DN) ) {
|
||||
state_flag = 0;
|
||||
ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_RING);
|
||||
|
||||
}
|
||||
}
|
||||
} else {
|
||||
state_flag = 0;
|
||||
ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_RING);
|
||||
}
|
||||
} else {
|
||||
/* if we are coming from idle state then we have already been here once before */
|
||||
if (ftdmchan->last_state != FTDM_CHANNEL_STATE_IDLE) {
|
||||
|
@ -1152,6 +1220,15 @@ ftdm_status_t ftdm_sangoma_ss7_process_state_change (ftdm_channel_t *ftdmchan)
|
|||
/**************************************************************************/
|
||||
case FTDM_CHANNEL_STATE_RING: /*incoming call request */
|
||||
|
||||
sngss7_clear_ckt_flag(sngss7_info, FLAG_INR_TX);
|
||||
sngss7_clear_ckt_flag(sngss7_info, FLAG_INR_SENT);
|
||||
sngss7_clear_ckt_flag(sngss7_info, FLAG_INR_RX);
|
||||
sngss7_clear_ckt_flag(sngss7_info, FLAG_INR_RX_DN);
|
||||
sngss7_clear_ckt_flag(sngss7_info, FLAG_INF_TX);
|
||||
sngss7_clear_ckt_flag(sngss7_info, FLAG_INF_SENT);
|
||||
sngss7_clear_ckt_flag(sngss7_info, FLAG_INF_RX);
|
||||
sngss7_clear_ckt_flag(sngss7_info, FLAG_INF_RX_DN);
|
||||
|
||||
if (ftdmchan->last_state == FTDM_CHANNEL_STATE_SUSPENDED) {
|
||||
SS7_DEBUG("re-entering state from processing block/unblock request ... do nothing\n");
|
||||
break;
|
||||
|
@ -1162,6 +1239,11 @@ ftdm_status_t ftdm_sangoma_ss7_process_state_change (ftdm_channel_t *ftdmchan)
|
|||
ftdm_sched_cancel_timer (sngss7_info->t35.sched, sngss7_info->t35.hb_timer_id);
|
||||
}
|
||||
|
||||
/* cancel t39 timer */
|
||||
if (sngss7_info->t39.hb_timer_id) {
|
||||
ftdm_sched_cancel_timer (sngss7_info->t39.sched, sngss7_info->t39.hb_timer_id);
|
||||
}
|
||||
|
||||
SS7_DEBUG_CHAN(ftdmchan, "Sending incoming call from %s to %s to FTDM core\n",
|
||||
ftdmchan->caller_data.ani.digits,
|
||||
ftdmchan->caller_data.dnis.digits);
|
||||
|
|
|
@ -395,6 +395,7 @@ typedef struct sng_isup_ckt {
|
|||
uint16_t t16;
|
||||
uint16_t t17;
|
||||
uint32_t t35;
|
||||
uint32_t t39;
|
||||
uint16_t tval;
|
||||
} sng_isup_ckt_t;
|
||||
|
||||
|
@ -466,6 +467,7 @@ typedef struct sng_ss7_cfg {
|
|||
sng_nsap_t nsap[MAX_NSAPS+1];
|
||||
sng_isap_t isap[MAX_ISAPS+1];
|
||||
sng_glare_resolution glareResolution;
|
||||
uint32_t force_inr;
|
||||
} sng_ss7_cfg_t;
|
||||
|
||||
typedef struct ftdm_sngss7_data {
|
||||
|
@ -517,6 +519,7 @@ typedef struct sngss7_chan_data {
|
|||
sngss7_glare_data_t glare;
|
||||
sngss7_timer_data_t t35;
|
||||
sngss7_timer_data_t t10;
|
||||
sngss7_timer_data_t t39;
|
||||
sngss7_group_data_t rx_grs;
|
||||
sngss7_group_data_t rx_gra;
|
||||
sngss7_group_data_t tx_grs;
|
||||
|
@ -584,6 +587,15 @@ typedef enum {
|
|||
FLAG_SENT_CPG = (1 << 17),
|
||||
FLAG_SUS_RECVD = (1 << 18),
|
||||
FLAG_T6_CANCELED = (1 << 19),
|
||||
FLAG_INR_TX = (1 << 20),
|
||||
FLAG_INR_SENT = (1 << 21),
|
||||
FLAG_INR_RX = (1 << 22),
|
||||
FLAG_INR_RX_DN = (1 << 23),
|
||||
FLAG_INF_TX = (1 << 24),
|
||||
FLAG_INF_SENT = (1 << 25),
|
||||
FLAG_INF_RX = (1 << 26),
|
||||
FLAG_INF_RX_DN = (1 << 27),
|
||||
FLAG_FULL_NUMBER = (1 << 28),
|
||||
FLAG_RELAY_DOWN = (1 << 30),
|
||||
FLAG_CKT_RECONFIG = (1 << 31)
|
||||
} sng_ckt_flag_t;
|
||||
|
@ -606,6 +618,14 @@ typedef enum {
|
|||
"INF_RESUME", \
|
||||
"INF_PAUSED", \
|
||||
"TX_ACM_SENT" \
|
||||
"TX_INR" \
|
||||
"INR_SENT" \
|
||||
"RX_INR" \
|
||||
"RX_INR_DN" \
|
||||
"TX_INF" \
|
||||
"INF SENT" \
|
||||
"RX_INF" \
|
||||
"RX_INF_DN" \
|
||||
"RELAY_DOWN", \
|
||||
"CKT_RECONFIG"
|
||||
FTDM_STR2ENUM_P(ftmod_ss7_ckt_state2flag, ftmod_ss7_ckt_flag2str, sng_ckt_flag_t)
|
||||
|
@ -820,6 +840,9 @@ void ft_to_sngss7_cgb(ftdm_channel_t * ftdmchan);
|
|||
void ft_to_sngss7_cgu(ftdm_channel_t * ftdmchan);
|
||||
void ft_to_sngss7_itx (ftdm_channel_t * ftdmchan);
|
||||
void ft_to_sngss7_txa (ftdm_channel_t * ftdmchan);
|
||||
void ft_to_sngss7_inr(ftdm_channel_t * ftdmchan);
|
||||
void ft_to_sngss7_inf(ftdm_channel_t *ftdmchan);
|
||||
|
||||
|
||||
|
||||
/* in ftmod_sangoma_ss7_in.c */
|
||||
|
@ -949,6 +972,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);
|
||||
void handle_isup_t10(void *userdata);
|
||||
void handle_isup_t39(void *userdata);
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
|
|
|
@ -237,6 +237,85 @@ void ft_to_sngss7_iam (ftdm_channel_t * ftdmchan)
|
|||
return;
|
||||
}
|
||||
|
||||
void ft_to_sngss7_inf(ftdm_channel_t *ftdmchan)
|
||||
{
|
||||
SiCnStEvnt evnt;
|
||||
sngss7_chan_data_t *sngss7_info = ftdmchan->call_data;
|
||||
/*
|
||||
const char *CallerId = NULL;
|
||||
const char *CallerCat = NULL;
|
||||
const char *sipvar;
|
||||
*/
|
||||
|
||||
memset (&evnt, 0x0, sizeof (evnt));
|
||||
|
||||
evnt.infoInd.eh.pres = PRSNT_NODEF;
|
||||
|
||||
evnt.infoInd.cgPtyAddrRespInd.pres = PRSNT_NODEF;
|
||||
evnt.infoInd.cgPtyAddrRespInd.val=CGPRTYADDRESP_INCL;
|
||||
copy_cgPtyNum_to_sngss7 (ftdmchan, &evnt.cgPtyNum);
|
||||
|
||||
|
||||
evnt.infoInd.cgPtyCatRespInd.pres = PRSNT_NODEF;
|
||||
evnt.infoInd.cgPtyCatRespInd.val = CGPRTYCATRESP_INCL;
|
||||
copy_cgPtyCat_to_sngss7 (ftdmchan, &evnt.cgPtyCat);
|
||||
|
||||
evnt.infoInd.chrgInfoRespInd.pres = PRSNT_NODEF;
|
||||
evnt.infoInd.chrgInfoRespInd.val = 0;
|
||||
|
||||
evnt.infoInd.solInfoInd.pres = PRSNT_NODEF;
|
||||
evnt.infoInd.solInfoInd.val = 0;
|
||||
|
||||
evnt.infoInd.holdProvInd.pres = PRSNT_NODEF;
|
||||
evnt.infoInd.holdProvInd.val = 0;
|
||||
|
||||
evnt.infoInd.spare.pres = PRSNT_NODEF;
|
||||
evnt.infoInd.spare.val = 0;
|
||||
|
||||
sng_cc_inf(1,
|
||||
sngss7_info->suInstId,
|
||||
sngss7_info->spInstId,
|
||||
sngss7_info->circuit->id,
|
||||
&evnt,
|
||||
INFORMATION);
|
||||
|
||||
SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Tx INF\n", sngss7_info->circuit->cic);
|
||||
|
||||
}
|
||||
|
||||
void ft_to_sngss7_inr(ftdm_channel_t *ftdmchan)
|
||||
{
|
||||
SiCnStEvnt evnt;
|
||||
sngss7_chan_data_t *sngss7_info = ftdmchan->call_data;
|
||||
|
||||
memset (&evnt, 0x0, sizeof (evnt));
|
||||
|
||||
evnt.infoReqInd.eh.pres = PRSNT_NODEF;
|
||||
evnt.infoReqInd.cgPtyAdReqInd.pres = PRSNT_NODEF;
|
||||
evnt.infoReqInd.cgPtyAdReqInd.val=CGPRTYADDREQ_REQ;
|
||||
|
||||
evnt.infoReqInd.holdingInd.pres = PRSNT_NODEF;
|
||||
evnt.infoReqInd.holdingInd.val = HOLD_NOTREQ;
|
||||
|
||||
evnt.infoReqInd.cgPtyCatReqInd.pres = PRSNT_NODEF;
|
||||
evnt.infoReqInd.cgPtyCatReqInd.val = CGPRTYCATREQ_REQ;
|
||||
|
||||
evnt.infoReqInd.chrgInfoReqInd.pres = PRSNT_NODEF;
|
||||
evnt.infoReqInd.chrgInfoReqInd.val = CHRGINFO_NOTREQ;
|
||||
|
||||
evnt.infoReqInd.malCaIdReqInd.pres = PRSNT_NODEF;
|
||||
evnt.infoReqInd.malCaIdReqInd.val = MLBG_INFONOTREQ;
|
||||
|
||||
sng_cc_inr(1,
|
||||
sngss7_info->suInstId,
|
||||
sngss7_info->spInstId,
|
||||
sngss7_info->circuit->id,
|
||||
&evnt,
|
||||
INFORMATREQ);
|
||||
|
||||
SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Tx INR\n", sngss7_info->circuit->cic);
|
||||
}
|
||||
|
||||
void ft_to_sngss7_acm (ftdm_channel_t * ftdmchan)
|
||||
{
|
||||
SS7_FUNC_TRACE_ENTER (__FUNCTION__);
|
||||
|
|
|
@ -186,7 +186,7 @@ ftdm_status_t copy_cgPtyNum_to_sngss7(ftdm_channel_t *ftdmchan, SiCgPtyNum *cgPt
|
|||
ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "Found user supplied Calling NADI value \"%s\"\n", clg_nadi);
|
||||
cgPtyNum->natAddrInd.val = atoi(clg_nadi);
|
||||
}
|
||||
ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "Calling Party Number Presentation Ind %d\n", cgPtyNum->presRest.val);
|
||||
ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "Calling Party Number NADI value %d\n", cgPtyNum->natAddrInd.val);
|
||||
|
||||
return copy_tknStr_to_sngss7(caller_data->cid_num.digits, &cgPtyNum->addrSig, &cgPtyNum->oddEven);
|
||||
}
|
||||
|
|
|
@ -49,7 +49,7 @@
|
|||
/******************************************************************************/
|
||||
|
||||
/* PROTOTYPES *****************************************************************/
|
||||
void handle_isup_t35(void *userdata);
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
/* FUNCTIONS ******************************************************************/
|
||||
|
@ -76,10 +76,13 @@ void handle_isup_t35(void *userdata)
|
|||
/* end the call */
|
||||
ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_CANCEL);
|
||||
|
||||
/* kill t10 if active */
|
||||
/* kill t10 t39 if active */
|
||||
if (sngss7_info->t10.hb_timer_id) {
|
||||
ftdm_sched_cancel_timer (sngss7_info->t10.sched, sngss7_info->t10.hb_timer_id);
|
||||
}
|
||||
if (sngss7_info->t39.hb_timer_id) {
|
||||
ftdm_sched_cancel_timer (sngss7_info->t39.sched, sngss7_info->t39.hb_timer_id);
|
||||
}
|
||||
|
||||
/*unlock*/
|
||||
ftdm_channel_unlock(ftdmchan);
|
||||
|
@ -109,6 +112,42 @@ void handle_isup_t10(void *userdata)
|
|||
SS7_FUNC_TRACE_EXIT(__FUNCTION__);
|
||||
}
|
||||
|
||||
void handle_isup_t39(void *userdata)
|
||||
{
|
||||
SS7_FUNC_TRACE_ENTER(__FUNCTION__);
|
||||
|
||||
sngss7_timer_data_t *timer = userdata;
|
||||
sngss7_chan_data_t *sngss7_info = timer->sngss7_info;
|
||||
ftdm_channel_t *ftdmchan = sngss7_info->ftdmchan;
|
||||
|
||||
/* now that we have the right channel...put a lock on it so no-one else can use it */
|
||||
ftdm_channel_lock(ftdmchan);
|
||||
|
||||
/* Q.764 2.2.5 Address incomplete (T35 expiry action is hangup with cause 28 according to Table A.1/Q.764) */
|
||||
SS7_ERROR("[Call-Control] Timer 39 expired on CIC = %d\n", sngss7_info->circuit->cic);
|
||||
|
||||
/* set the flag to indicate this hangup is started from the local side */
|
||||
sngss7_set_ckt_flag(sngss7_info, FLAG_LOCAL_REL);
|
||||
|
||||
/* hang up on timer expiry */
|
||||
ftdmchan->caller_data.hangup_cause = FTDM_CAUSE_INVALID_NUMBER_FORMAT;
|
||||
|
||||
/* end the call */
|
||||
ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_CANCEL);
|
||||
|
||||
/* kill t10 t35 if active */
|
||||
if (sngss7_info->t10.hb_timer_id) {
|
||||
ftdm_sched_cancel_timer (sngss7_info->t10.sched, sngss7_info->t10.hb_timer_id);
|
||||
}
|
||||
if (sngss7_info->t35.hb_timer_id) {
|
||||
ftdm_sched_cancel_timer (sngss7_info->t35.sched, sngss7_info->t35.hb_timer_id);
|
||||
}
|
||||
|
||||
/*unlock*/
|
||||
ftdm_channel_unlock(ftdmchan);
|
||||
|
||||
SS7_FUNC_TRACE_EXIT(__FUNCTION__);
|
||||
}
|
||||
/******************************************************************************/
|
||||
/* For Emacs:
|
||||
* Local Variables:
|
||||
|
|
|
@ -146,6 +146,7 @@ typedef struct sng_ccSpan
|
|||
uint32_t t16;
|
||||
uint32_t t17;
|
||||
uint32_t t35;
|
||||
uint32_t t39;
|
||||
uint32_t tval;
|
||||
} sng_ccSpan_t;
|
||||
|
||||
|
@ -487,6 +488,7 @@ static int ftmod_ss7_parse_sng_gen(ftdm_conf_node_t *sng_gen)
|
|||
|
||||
/* Set the transparent_iam_max_size to default value */
|
||||
g_ftdm_sngss7_data.cfg.transparent_iam_max_size=800;
|
||||
g_ftdm_sngss7_data.cfg.force_inr = 0;
|
||||
|
||||
/* extract all the information from the parameters */
|
||||
for (i = 0; i < num_parms; i++) {
|
||||
|
@ -508,6 +510,14 @@ static int ftmod_ss7_parse_sng_gen(ftdm_conf_node_t *sng_gen)
|
|||
ftmod_ss7_set_glare_resolution (parm->val);
|
||||
SS7_DEBUG("Found glare resolution configuration = %d %s\n", g_ftdm_sngss7_data.cfg.glareResolution, parm->val );
|
||||
}
|
||||
else if (!strcasecmp(parm->var, "force-inr")) {
|
||||
if (!strcasecmp(parm->val, "true")) {
|
||||
g_ftdm_sngss7_data.cfg.force_inr = 1;
|
||||
} else {
|
||||
g_ftdm_sngss7_data.cfg.force_inr = 0;
|
||||
}
|
||||
SS7_DEBUG("Found INR force configuration = %s\n", parm->val );
|
||||
}
|
||||
else {
|
||||
SS7_ERROR("Found an invalid parameter \"%s\"!\n", parm->val);
|
||||
return FTDM_FAIL;
|
||||
|
@ -2062,6 +2072,11 @@ static int ftmod_ss7_parse_cc_span(ftdm_conf_node_t *cc_span)
|
|||
sng_ccSpan.t35 = atoi(parm->val);
|
||||
SS7_DEBUG("Found isup t35 = %d\n",sng_ccSpan.t35);
|
||||
/**********************************************************************/
|
||||
} else if (!strcasecmp(parm->var, "isup.t39")) {
|
||||
/**********************************************************************/
|
||||
sng_ccSpan.t39 = atoi(parm->val);
|
||||
SS7_DEBUG("Found isup t39 = %d\n",sng_ccSpan.t39);
|
||||
/**********************************************************************/
|
||||
} else if (!strcasecmp(parm->var, "isup.tval")) {
|
||||
/**********************************************************************/
|
||||
sng_ccSpan.tval = atoi(parm->val);
|
||||
|
@ -3044,6 +3059,12 @@ static int ftmod_ss7_fill_in_ccSpan(sng_ccSpan_t *ccSpan)
|
|||
} else {
|
||||
g_ftdm_sngss7_data.cfg.isupCkt[x].t35 = ccSpan->t35;
|
||||
}
|
||||
if (ccSpan->t39 == 0) {
|
||||
g_ftdm_sngss7_data.cfg.isupCkt[x].t39 = 120;
|
||||
} else {
|
||||
g_ftdm_sngss7_data.cfg.isupCkt[x].t39 = ccSpan->t39;
|
||||
}
|
||||
|
||||
if (ccSpan->tval == 0) {
|
||||
g_ftdm_sngss7_data.cfg.isupCkt[x].tval = 10;
|
||||
} else {
|
||||
|
@ -3148,6 +3169,13 @@ static int ftmod_ss7_fill_in_circuits(sng_span_t *sngSpan)
|
|||
ss7_info->t10.callback = handle_isup_t10;
|
||||
ss7_info->t10.sngss7_info = ss7_info;
|
||||
|
||||
/* prepare the timer structures */
|
||||
ss7_info->t39.sched = ((sngss7_span_data_t *)(ftdmspan->signal_data))->sched;
|
||||
ss7_info->t39.counter = 1;
|
||||
ss7_info->t39.beat = (isupCkt->t39) * 100; /* beat is in ms, t39 is in 100ms */
|
||||
ss7_info->t39.callback = handle_isup_t39;
|
||||
ss7_info->t39.sngss7_info = ss7_info;
|
||||
|
||||
|
||||
/**************************************************************************/
|
||||
} /* for (i == 1; i < ftdmspan->chan_count; i++) */
|
||||
|
|
Loading…
Reference in New Issue