From 735f5c5059c6fc4f35b7b83ca19b66802c3050f9 Mon Sep 17 00:00:00 2001 From: Richard Mudgett Date: Thu, 8 Nov 2012 21:12:35 +0000 Subject: chan_dahdi/SS7: Made reject incoming call for an in-alarm or blocked channel. If a SS7 call comes in requesting a CIC that is in-alarm, the call is accepted and connects if the extension exists in the dialplan. The call does not have any audio. * Made release the call immediately with circuit congestion cause. (closes issue ASTERISK-20204) Reported by: Tuan Le Patches: jira_asterisk_20204_v1.8.patch (license #5621) patch uploaded by rmudgett ........ Merged revisions 376058 from http://svn.asterisk.org/svn/asterisk/branches/1.8 ........ Merged revisions 376059 from http://svn.asterisk.org/svn/asterisk/branches/10 ........ Merged revisions 376060 from http://svn.asterisk.org/svn/asterisk/branches/11 git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@376061 65c4cc65-6c06-0410-ace0-fbb531ad65f3 --- channels/sig_ss7.c | 51 +++++++++++++++++++++++++++++---------------------- 1 file changed, 29 insertions(+), 22 deletions(-) (limited to 'channels/sig_ss7.c') diff --git a/channels/sig_ss7.c b/channels/sig_ss7.c index 795887123..d5a92c332 100644 --- a/channels/sig_ss7.c +++ b/channels/sig_ss7.c @@ -291,6 +291,24 @@ static void sig_ss7_handle_link_exception(struct sig_ss7_linkset *linkset, int w } } +/*! + * \internal + * \brief Determine if a private channel structure is available. + * + * \param pvt Channel to determine if available. + * + * \return TRUE if the channel is available. + */ +static int sig_ss7_is_chan_available(struct sig_ss7_chan *pvt) +{ + if (!pvt->inalarm && !pvt->owner && !pvt->ss7call + && pvt->call_level == SIG_SS7_CALL_LEVEL_IDLE + && !pvt->locallyblocked && !pvt->remotelyblocked) { + return 1; + } + return 0; +} + /*! * \internal * \brief Obtain the sig_ss7 owner channel lock if the owner exists. @@ -589,7 +607,7 @@ static void ss7_start_call(struct sig_ss7_chan *p, struct sig_ss7_linkset *links ast_log(LOG_WARNING, "Unable to start PBX on CIC %d\n", p->cic); ast_mutex_lock(&linkset->lock); sig_ss7_lock_private(p); - isup_rel(linkset->ss7, p->ss7call, -1); + isup_rel(linkset->ss7, p->ss7call, AST_CAUSE_SWITCH_CONGESTION); p->call_level = SIG_SS7_CALL_LEVEL_IDLE; p->alreadyhungup = 1; ast_callid_threadstorage_auto_clean(callid, callid_created); @@ -975,12 +993,12 @@ void *ss7_linkset(void *data) * We have not sent our IAM yet and we never will at this point. */ p->alreadyhungup = 1; - isup_rel(ss7, e->iam.call, -1); + isup_rel(ss7, e->iam.call, AST_CAUSE_NORMAL_CIRCUIT_CONGESTION); } p->call_level = SIG_SS7_CALL_LEVEL_GLARE; if (p->owner) { - ss7_queue_pvt_cause_data(p->owner, "SS7 ISUP_EVENT_IAM (glare)", AST_CAUSE_NORMAL_CLEARING); - ast_channel_hangupcause_set(p->owner, AST_CAUSE_NORMAL_CLEARING); + ss7_queue_pvt_cause_data(p->owner, "SS7 ISUP_EVENT_IAM (glare)", AST_CAUSE_NORMAL_CIRCUIT_CONGESTION); + ast_channel_hangupcause_set(p->owner, AST_CAUSE_NORMAL_CIRCUIT_CONGESTION); ast_softhangup_nolock(p->owner, AST_SOFTHANGUP_DEV); ast_channel_unlock(p->owner); } @@ -993,6 +1011,13 @@ void *ss7_linkset(void *data) */ ast_assert(!p->owner); + if (!sig_ss7_is_chan_available(p)) { + /* Circuit is likely blocked or in alarm. */ + isup_rel(ss7, e->iam.call, AST_CAUSE_NORMAL_CIRCUIT_CONGESTION); + sig_ss7_unlock_private(p); + break; + } + /* Mark channel as in use so no outgoing call will steal it. */ p->call_level = SIG_SS7_CALL_LEVEL_ALLOCATED; p->ss7call = e->iam.call; @@ -1443,24 +1468,6 @@ int sig_ss7_add_sigchan(struct sig_ss7_linkset *linkset, int which, int ss7type, return 0; } -/*! - * \internal - * \brief Determine if a private channel structure is available. - * - * \param pvt Channel to determine if available. - * - * \return TRUE if the channel is available. - */ -static int sig_ss7_is_chan_available(struct sig_ss7_chan *pvt) -{ - if (!pvt->inalarm && !pvt->owner && !pvt->ss7call - && pvt->call_level == SIG_SS7_CALL_LEVEL_IDLE - && !pvt->locallyblocked && !pvt->remotelyblocked) { - return 1; - } - return 0; -} - /*! * \brief Determine if the specified channel is available for an outgoing call. * \since 1.8 -- cgit v1.2.3