[asterisk-commits] mattf: branch mattf/bug13495 r160762 - in /team/mattf/bug13495: channels/ main/
SVN commits to the Asterisk project
asterisk-commits at lists.digium.com
Wed Dec 3 15:31:23 CST 2008
Author: mattf
Date: Wed Dec 3 15:31:22 2008
New Revision: 160762
URL: http://svn.digium.com/view/asterisk?view=rev&rev=160762
Log:
Commit of chan_dahdi portion of #13495
Modified:
team/mattf/bug13495/channels/chan_dahdi.c
team/mattf/bug13495/main/ast_expr2.c
team/mattf/bug13495/main/ast_expr2.h
Modified: team/mattf/bug13495/channels/chan_dahdi.c
URL: http://svn.digium.com/view/asterisk/team/mattf/bug13495/channels/chan_dahdi.c?view=diff&rev=160762&r1=160761&r2=160762
==============================================================================
--- team/mattf/bug13495/channels/chan_dahdi.c (original)
+++ team/mattf/bug13495/channels/chan_dahdi.c Wed Dec 3 15:31:22 2008
@@ -381,7 +381,11 @@
#define SS7_NAI_DYNAMIC -1
-#define LINKSET_FLAG_EXPLICITACM (1 << 0)
+#define LINKSET_FLAG_EXPLICITACM (1 << 0)
+#define LINKSET_FLAG_INITIALHWBLO (1 << 1)
+
+#define SS7_BLOCKED_MAINTENANCE (1 << 0)
+#define SS7_BLOCKED_HARDWARE (1 << 1)
struct dahdi_ss7 {
pthread_t master; /*!< Thread of master */
@@ -401,6 +405,7 @@
char nationalprefix[10]; /*!< area access code ('0' for european dialplans) */
char subscriberprefix[20]; /*!< area access code + area code ('0'+area code for european dialplans) */
char unknownprefix[20]; /*!< for unknown dialplans */
+ char networkroutedprefix[20];
struct ss7 *ss7;
struct dahdi_pvt *pvts[MAX_CHANNELS]; /*!< Member channel pvt structs */
int flags; /*!< Linkset flags */
@@ -638,8 +643,8 @@
unsigned int mwisendactive:1; /*!< a MWI message sending thread is active */
/* Channel state or unavilability flags */
unsigned int inservice:1;
- unsigned int locallyblocked:1;
- unsigned int remotelyblocked:1;
+ unsigned int locallyblocked:2;
+ unsigned int remotelyblocked:2;
#if defined(HAVE_PRI) || defined(HAVE_SS7)
unsigned int rlt:1;
unsigned int alerting:1;
@@ -649,6 +654,10 @@
unsigned int progress:1;
unsigned int resetting:1;
unsigned int setup_ack:1;
+#endif
+#if HAVE_SS7
+ unsigned int do_hangup; /* what have to do in chan_dahdi */
+ unsigned int called_complete;
#endif
unsigned int use_smdi:1; /* Whether to use SMDI on this channel */
struct mwisend_info mwisend_data;
@@ -754,6 +763,12 @@
char gen_dig_number[50];
char orig_called_num[50];
char redirecting_num[50];
+ unsigned char redirect_counter;
+ unsigned char redirect_info;
+ unsigned char redirect_info_ind;
+ unsigned char redirect_info_orig_reas;
+ unsigned char redirect_info_counter;
+ unsigned char redirect_info_reas;
char generic_name[50];
unsigned char gen_add_num_plan;
unsigned char gen_add_nai;
@@ -773,6 +788,9 @@
int cic; /*!< CIC associated with channel */
unsigned int dpc; /*!< CIC's DPC */
unsigned int loopedback:1;
+ char cug_interlock_ni[5];
+ unsigned short cug_interlock_code;
+ unsigned char cug_indicator;
#endif
char begindigit;
int muting;
@@ -836,7 +854,8 @@
.internationalprefix = "",
.nationalprefix = "",
.subscriberprefix = "",
- .unknownprefix = ""
+ .unknownprefix = "",
+ .networkroutedprefix = "",
},
#endif
.chan = {
@@ -957,6 +976,9 @@
#endif
#ifdef HAVE_SS7
+static int ss7_find_alloc_call(struct dahdi_pvt *p);
+static int ss7_do_rsc(struct dahdi_pvt *p);
+
static inline void ss7_rel(struct dahdi_ss7 *ss7)
{
ast_mutex_unlock(&ss7->lock);
@@ -2160,6 +2182,31 @@
{
return cid_pres & 0x03;
}
+
+static int ss7_parse_prefix(struct dahdi_pvt *p, const char *number, char *nai)
+{
+ int strip = 0;
+
+ if (strncmp(number, p->ss7->internationalprefix, strlen(p->ss7->internationalprefix)) == 0) {
+ strip = strlen(p->ss7->internationalprefix);
+ *nai = SS7_NAI_INTERNATIONAL;
+ } else if (strncmp(number, p->ss7->nationalprefix, strlen(p->ss7->nationalprefix)) == 0) {
+ strip = strlen(p->ss7->nationalprefix);
+ *nai = SS7_NAI_NATIONAL;
+ } else if (strncmp(number, p->ss7->networkroutedprefix, strlen(p->ss7->networkroutedprefix)) == 0) {
+ strip = strlen(p->ss7->networkroutedprefix);
+ *nai = SS7_NAI_NETWORKROUTED;
+ } else if (strncmp(number, p->ss7->unknownprefix, strlen(p->ss7->unknownprefix)) == 0) {
+ strip = strlen(p->ss7->unknownprefix);
+ *nai = SS7_NAI_UNKNOWN;
+ } else if (strncmp(number, p->ss7->subscriberprefix, strlen(p->ss7->subscriberprefix)) == 0) {
+ strip = strlen(p->ss7->subscriberprefix);
+ *nai = SS7_NAI_SUBSCRIBER;
+ } else
+ *nai = SS7_NAI_SUBSCRIBER;
+
+ return strip;
+}
#endif
static int dahdi_call(struct ast_channel *ast, char *rdest, int timeout)
@@ -2462,6 +2509,16 @@
int called_nai_strip;
char ss7_calling_nai;
int calling_nai_strip;
+ char ss7_orig_called_nai;
+ int orig_called_num_nai_strip;
+ char ss7_redirecting_num_nai;
+ int redirecting_num_nai_strip;
+ unsigned char redirect_info_ind_num;
+ unsigned char redirect_info_orig_reas_num;
+ unsigned char redirect_info_counter_num;
+ unsigned char redirect_info_reas_num;
+ unsigned char ss7_cug_indicator;
+ const char *ss7_redirect_counter;
const char *charge_str = NULL;
const char *gen_address = NULL;
const char *gen_digits = NULL;
@@ -2474,7 +2531,17 @@
const char *call_ref_id = NULL;
const char *call_ref_pc = NULL;
const char *send_far = NULL;
-
+ const char *redirecting_number = NULL;
+ const char *ss7_orig_called_num = NULL;
+ const char *redirect_info_ind = NULL;
+ const char *redirect_info_orig_reas = NULL;
+ const char *redirect_info_counter = NULL;
+ const char *redirect_info_reas = NULL;
+ const char *col_req = NULL;
+ const char *ss7_cug_indicator_str;
+ const char *ss7_cug_interlock_ni;
+ const char *ss7_cug_interlock_code;
+
c = strchr(dest, '/');
if (c)
c++;
@@ -2504,35 +2571,24 @@
called_nai_strip = 0;
ss7_called_nai = p->ss7->called_nai;
- if (ss7_called_nai == SS7_NAI_DYNAMIC) { /* compute dynamically */
- if (strncmp(c + p->stripmsd, p->ss7->internationalprefix, strlen(p->ss7->internationalprefix)) == 0) {
- called_nai_strip = strlen(p->ss7->internationalprefix);
- ss7_called_nai = SS7_NAI_INTERNATIONAL;
- } else if (strncmp(c + p->stripmsd, p->ss7->nationalprefix, strlen(p->ss7->nationalprefix)) == 0) {
- called_nai_strip = strlen(p->ss7->nationalprefix);
- ss7_called_nai = SS7_NAI_NATIONAL;
- } else {
- ss7_called_nai = SS7_NAI_SUBSCRIBER;
- }
- }
+
+ if (ss7_called_nai == SS7_NAI_DYNAMIC) /* compute dynamically */
+ called_nai_strip = ss7_parse_prefix(p, c + p->stripmsd, &ss7_called_nai);
+
isup_set_called(p->ss7call, c + p->stripmsd + called_nai_strip, ss7_called_nai, p->ss7->ss7);
calling_nai_strip = 0;
ss7_calling_nai = p->ss7->calling_nai;
- if ((l != NULL) && (ss7_calling_nai == SS7_NAI_DYNAMIC)) { /* compute dynamically */
- if (strncmp(l, p->ss7->internationalprefix, strlen(p->ss7->internationalprefix)) == 0) {
- calling_nai_strip = strlen(p->ss7->internationalprefix);
- ss7_calling_nai = SS7_NAI_INTERNATIONAL;
- } else if (strncmp(l, p->ss7->nationalprefix, strlen(p->ss7->nationalprefix)) == 0) {
- calling_nai_strip = strlen(p->ss7->nationalprefix);
- ss7_calling_nai = SS7_NAI_NATIONAL;
- } else {
- ss7_calling_nai = SS7_NAI_SUBSCRIBER;
- }
- }
- isup_set_calling(p->ss7call, l ? (l + calling_nai_strip) : NULL, ss7_calling_nai,
- p->use_callingpres ? cid_pres2ss7pres(ast->cid.cid_pres) : (l ? SS7_PRESENTATION_ALLOWED : SS7_PRESENTATION_RESTRICTED),
- p->use_callingpres ? cid_pres2ss7screen(ast->cid.cid_pres) : SS7_SCREENING_USER_PROVIDED );
+
+ if (l && ss7_calling_nai == SS7_NAI_DYNAMIC) /* compute dynamically */
+ calling_nai_strip = ss7_parse_prefix(p, l, &ss7_calling_nai);
+
+ if (ast->cid.cid_pres == AST_PRES_UNAVAILABLE)
+ isup_set_calling(p->ss7call, NULL, 0, SS7_PRESENTATION_ADDR_NOT_AVAILABLE, 3);
+ else
+ isup_set_calling(p->ss7call, l ? (l + calling_nai_strip) : NULL, ss7_calling_nai,
+ p->use_callingpres ? cid_pres2ss7pres(ast->cid.cid_pres) : (l ? SS7_PRESENTATION_ALLOWED : SS7_PRESENTATION_RESTRICTED),
+ p->use_callingpres ? cid_pres2ss7screen(ast->cid.cid_pres) : SS7_SCREENING_USER_PROVIDED );
isup_set_oli(p->ss7call, ast->cid.cid_ani2);
isup_init_call(p->ss7->ss7, p->ss7call, p->cic, p->dpc);
@@ -2580,6 +2636,118 @@
send_far = pbx_builtin_getvar_helper(ast, "SS7_SEND_FAR");
if ((send_far) && ((strncmp("NO", send_far, strlen(send_far))) != 0 ))
(isup_far(p->ss7->ss7, p->ss7call));
+
+ redirecting_number = pbx_builtin_getvar_helper(ast, "SS7_REDIRECTING_NUMBER");
+
+ if (redirecting_number) {
+ redirecting_num_nai_strip = 0;
+ ss7_redirecting_num_nai = p->ss7->calling_nai;
+ if (ss7_redirecting_num_nai == SS7_NAI_DYNAMIC)
+ redirecting_num_nai_strip = ss7_parse_prefix(p, redirecting_number, &ss7_redirecting_num_nai);
+ isup_set_redirecting_number(p->ss7call, redirecting_number + redirecting_num_nai_strip, ss7_redirecting_num_nai, SS7_PRESENTATION_RESTRICTED, 3);
+ }
+
+ ss7_redirect_counter = pbx_builtin_getvar_helper(ast, "SS7_REDIRECT_COUNTER");
+ if (ss7_redirect_counter)
+ isup_set_redirect_counter(p->ss7call, atoi(ss7_redirect_counter));
+
+ ss7_orig_called_num = pbx_builtin_getvar_helper(ast, "SS7_ORIG_CALLED_NUM");
+ if (ss7_orig_called_num) {
+ orig_called_num_nai_strip = 0;
+ ss7_orig_called_nai = p->ss7->called_nai;
+ if (ss7_orig_called_nai == SS7_NAI_DYNAMIC)
+ orig_called_num_nai_strip = ss7_parse_prefix(p, ss7_orig_called_num, &ss7_orig_called_nai);
+ isup_set_orig_called_num(p->ss7call, ss7_orig_called_num + orig_called_num_nai_strip, ss7_orig_called_nai,
+ SS7_PRESENTATION_RESTRICTED, 3);
+ }
+
+ redirect_info_ind = pbx_builtin_getvar_helper(ast, "SS7_REDIRECT_INFO_IND");
+ if (redirect_info_ind && redirect_info_ind[0] != '\0') {
+ if (!strcasecmp(redirect_info_ind, "NO_REDIRECTION"))
+ redirect_info_ind_num = 0;
+ else if (!strcasecmp(redirect_info_ind, "CALL_REROUTED_PRES_ALLOWED"))
+ redirect_info_ind_num = 1;
+ else if (!strcasecmp(redirect_info_ind, "CALL_REROUTED_INFO_RESTRICTED"))
+ redirect_info_ind_num = 2;
+ else if (!strcasecmp(redirect_info_ind, "CALL_DIVERTED_PRES_ALLOWED"))
+ redirect_info_ind_num = 3;
+ else if (!strcasecmp(redirect_info_ind, "CALL_DIVERTED_INFO_RESTRICTED"))
+ redirect_info_ind_num = 4;
+ else if (!strcasecmp(redirect_info_ind, "CALL_REROUTED_PRES_RESTRICTED"))
+ redirect_info_ind_num = 5;
+ else if (!strcasecmp(redirect_info_ind, "CALL_DIVERTED_PRES_RESTRICTED"))
+ redirect_info_ind_num = 6;
+ else if (!strcasecmp(redirect_info_ind, "SPARE"))
+ redirect_info_ind_num = 7;
+ else
+ redirect_info_ind_num = 0;
+
+ redirect_info_orig_reas = pbx_builtin_getvar_helper(ast, "SS7_REDIRECT_INFO_ORIG_REAS");
+ if (redirect_info_orig_reas) {
+ if (!strcasecmp(redirect_info_orig_reas, "UNKNOWN"))
+ redirect_info_orig_reas_num = 0;
+ else if (!strcasecmp(redirect_info_orig_reas, "USER-BUSY"))
+ redirect_info_orig_reas_num = 1;
+ else if (!strcasecmp(redirect_info_orig_reas, "NO-ANSWER"))
+ redirect_info_orig_reas_num = 2;
+ else if (!strcasecmp(redirect_info_orig_reas, "UNCONDITIONAL"))
+ redirect_info_orig_reas_num = 3;
+ else
+ redirect_info_orig_reas_num = 0;
+ } else
+ redirect_info_orig_reas_num = 0;
+
+ redirect_info_counter = pbx_builtin_getvar_helper(ast, "SS7_REDIRECT_INFO_COUNTER");
+ if (redirect_info_counter)
+ redirect_info_counter_num = atoi(redirect_info_counter);
+ else
+ redirect_info_counter_num = 5; /* Avoiding call forwarding loops!!! */
+
+ redirect_info_reas = pbx_builtin_getvar_helper(ast, "SS7_REDIRECT_INFO_REAS");
+ if (redirect_info_reas) {
+ if (!strcasecmp(redirect_info_reas, "UNKNOWN"))
+ redirect_info_reas_num = 0;
+ else if (!strcasecmp(redirect_info_reas, "USER-BUSY"))
+ redirect_info_reas_num = 1;
+ else if (!strcasecmp(redirect_info_reas, "NO-ANSWER"))
+ redirect_info_reas_num = 2;
+ else if (!strcasecmp(redirect_info_reas, "UNCONDITIONAL"))
+ redirect_info_reas_num = 3;
+ else if (!strcasecmp(redirect_info_reas, "DEFLECTION_DURING_ALERTING"))
+ redirect_info_reas_num = 4;
+ else if (!strcasecmp(redirect_info_reas, "DEFLECTION_IMMEDIATE_RESPONSE"))
+ redirect_info_reas_num = 5;
+ else if (!strcasecmp(redirect_info_reas, "UNAVAILABLE"))
+ redirect_info_reas_num = 6;
+ else
+ redirect_info_reas_num = 0;
+ } else
+ redirect_info_reas_num = 0;
+
+ isup_set_redirectiong_info(p->ss7call, redirect_info_ind_num, redirect_info_orig_reas_num,
+ redirect_info_counter_num, redirect_info_reas_num);
+ }
+
+ col_req = pbx_builtin_getvar_helper(ast, "SS7_COL_REQUEST");
+ if (ast_true(col_req))
+ isup_set_col_req(p->ss7call);
+
+ ss7_cug_indicator_str = pbx_builtin_getvar_helper(ast, "SS7_CUG_INDICATOR");
+ if (ss7_cug_indicator_str && ss7_cug_indicator_str[0]) {
+ if (!strcasecmp(ss7_cug_indicator_str, "OUTGOING_ALLOWED"))
+ ss7_cug_indicator = ISUP_CUG_OUTGOING_ALLOWED;
+ else if (!strcasecmp(ss7_cug_indicator_str, "OUTGOING_NOT_ALLOWED"))
+ ss7_cug_indicator = ISUP_CUG_OUTGOING_NOT_ALLOWED;
+ else
+ ss7_cug_indicator = ISUP_CUG_NON;
+
+ if (ss7_cug_indicator != ISUP_CUG_NON) {
+ ss7_cug_interlock_code = pbx_builtin_getvar_helper(ast, "SS7_CUG_INTERLOCK_CODE");
+ ss7_cug_interlock_ni = pbx_builtin_getvar_helper(ast, "SS7_CUG_INTERLOCK_NI");
+ if (ss7_cug_interlock_code && ss7_cug_interlock_ni && strlen(ss7_cug_interlock_ni) == 4)
+ isup_set_cug(p->ss7call, ss7_cug_indicator, ss7_cug_interlock_ni, atoi(ss7_cug_interlock_code));
+ }
+ }
ast_channel_unlock(ast);
@@ -3344,7 +3512,7 @@
if (p->ss7) {
if (p->ss7call) {
if (!ss7_grab(p, p->ss7)) {
- if (!p->alreadyhungup) {
+ if (p->do_hangup == SS7_HANGUP_SEND_REL) {
const char *cause = pbx_builtin_getvar_helper(ast,"SS7_CAUSE");
int icause = ast->hangupcause ? ast->hangupcause : -1;
@@ -3352,11 +3520,30 @@
if (atoi(cause))
icause = atoi(cause);
}
+ if (icause > 255)
+ icause = 16;
+
isup_rel(p->ss7->ss7, p->ss7call, icause);
- ss7_rel(p->ss7);
- p->alreadyhungup = 1;
- } else
- ast_log(LOG_WARNING, "Trying to hangup twice!\n");
+ p->do_hangup = SS7_HANGUP_DO_NOTHING;
+ } else if (p->do_hangup == SS7_HANGUP_SEND_RSC) {
+ ss7_do_rsc(p);
+ p->do_hangup = SS7_HANGUP_DO_NOTHING;
+ } else if (p->do_hangup == SS7_HANGUP_SEND_RLC) {
+ isup_rlc(p->ss7->ss7, p->ss7call);
+ isup_free_call(p->ss7->ss7, p->ss7call);
+ p->ss7call = NULL;
+ p->do_hangup = SS7_HANGUP_DO_NOTHING;
+ } else if (p->do_hangup == SS7_HANGUP_FREE_CALL) {
+ p->do_hangup = SS7_HANGUP_DO_NOTHING;
+ isup_free_call(p->ss7->ss7, p->ss7call);
+ p->ss7call = NULL;
+ } else if (p->do_hangup == SS7_HANGUP_REEVENT_IAM) {
+ isup_event_iam(p->ss7->ss7, p->ss7call, p->dpc);
+ p->do_hangup = SS7_HANGUP_SEND_REL;
+ } else if (p->do_hangup == SS7_HANGUP_DO_NOTHING) {
+ p->ss7call = isup_free_call_if_clear(p->ss7->ss7, p->ss7call);
+ }
+ ss7_rel(p->ss7);
} else {
ast_log(LOG_WARNING, "Unable to grab SS7 on CIC %d\n", p->cic);
res = -1;
@@ -3601,6 +3788,27 @@
#ifdef HAVE_SS7
case SIG_SS7:
if (!ss7_grab(p, p->ss7)) {
+ const char *connected_num, *connected_pres_str;
+ unsigned char connected_pres;
+ char connected_nai;
+ int connected_strip = 0;
+
+ connected_num = pbx_builtin_getvar_helper(ast, "SS7_CONNECTED_NUMBER");
+ if (connected_num) {
+ if (p->ss7->called_nai == SS7_NAI_DYNAMIC)
+ connected_strip = ss7_parse_prefix(p, connected_num, &connected_nai);
+ else
+ connected_nai = p->ss7->called_nai;
+
+ connected_pres_str = pbx_builtin_getvar_helper(ast, "SS7_CONNECTED_PRES");
+
+ if (connected_pres_str)
+ connected_pres = cid_pres2ss7pres(ast_parse_caller_presentation(connected_pres_str));
+ else
+ connected_pres = SS7_PRESENTATION_RESTRICTED;
+
+ isup_set_connected(p->ss7call, connected_num + connected_strip, connected_nai, connected_pres, SS7_SCREENING_NETWORK_PROVIDED);
+ }
p->proceeding = 1;
res = isup_anm(p->ss7->ss7, p->ss7call);
ss7_rel(p->ss7);
@@ -5940,6 +6148,7 @@
}
if (!p->proceeding && p->sig == SIG_SS7 && p->ss7 && !p->outgoing) {
+
if (p->ss7->ss7) {
ss7_grab(p, p->ss7);
isup_acm(p->ss7->ss7, p->ss7call);
@@ -6026,6 +6235,16 @@
} else
#endif
ast_moh_start(chan, data, p->mohinterpret);
+#ifdef HAVE_SS7
+ if (p->ss7) {
+ if (!ss7_grab(p, p->ss7)) {
+ if (p->ss7call)
+ isup_sus(p->ss7->ss7, p->ss7call, 0);
+ ss7_rel(p->ss7);
+ } else
+ ast_log(LOG_WARNING, "Unable to grab SS& on linkset %d\n", p->span);
+ }
+#endif
break;
case AST_CONTROL_UNHOLD:
#ifdef HAVE_PRI
@@ -6038,6 +6257,16 @@
} else
#endif
ast_moh_stop(chan);
+#ifdef HAVE_SS7
+ if (p->ss7) {
+ if (!ss7_grab(p, p->ss7)) {
+ if (p->ss7call)
+ isup_res(p->ss7->ss7, p->ss7call, 0);
+ ss7_rel(p->ss7);
+ } else
+ ast_log(LOG_WARNING, "Unable to grab SS& on linkset %d\n", p->span);
+ }
+#endif
break;
case AST_CONTROL_RADIO_KEY:
if (p->radio)
@@ -6240,6 +6469,9 @@
/* Assume calls are not idle calls unless we're told differently */
i->isidlecall = 0;
i->alreadyhungup = 0;
+#endif
+#ifdef HAVE_SS7
+ i->do_hangup = SS7_HANGUP_SEND_REL;
#endif
/* clear the fake event in case we posted one before we had ast_channel */
i->fake_event = 0;
@@ -8587,13 +8819,14 @@
tmp->ss7call = NULL;
ss7->pvts[ss7->numchans++] = tmp;
- ast_copy_string(linksets[span].internationalprefix, conf->ss7.internationalprefix, sizeof(linksets[span].internationalprefix));
- ast_copy_string(linksets[span].nationalprefix, conf->ss7.nationalprefix, sizeof(linksets[span].nationalprefix));
- ast_copy_string(linksets[span].subscriberprefix, conf->ss7.subscriberprefix, sizeof(linksets[span].subscriberprefix));
- ast_copy_string(linksets[span].unknownprefix, conf->ss7.unknownprefix, sizeof(linksets[span].unknownprefix));
-
- linksets[span].called_nai = conf->ss7.called_nai;
- linksets[span].calling_nai = conf->ss7.calling_nai;
+ ast_copy_string(ss7->internationalprefix, conf->ss7.internationalprefix, sizeof(ss7->internationalprefix));
+ ast_copy_string(ss7->nationalprefix, conf->ss7.nationalprefix, sizeof(ss7->nationalprefix));
+ ast_copy_string(ss7->subscriberprefix, conf->ss7.subscriberprefix, sizeof(ss7->subscriberprefix));
+ ast_copy_string(ss7->unknownprefix, conf->ss7.unknownprefix, sizeof(ss7->unknownprefix));
+ ast_copy_string(ss7->networkroutedprefix, conf->ss7.networkroutedprefix, sizeof(ss7->networkroutedprefix));
+
+ ss7->called_nai = conf->ss7.called_nai;
+ ss7->calling_nai = conf->ss7.calling_nai;
}
#endif
#ifdef HAVE_PRI
@@ -8965,9 +9198,11 @@
tmp->sendcalleridafter = conf->chan.sendcalleridafter;
if (!here) {
tmp->locallyblocked = tmp->remotelyblocked = 0;
- if ((chan_sig == SIG_PRI) || (chan_sig == SIG_BRI) || (chan_sig == SIG_BRI_PTMP) || (chan_sig == SIG_SS7))
+ if ((chan_sig == SIG_PRI) || (chan_sig == SIG_BRI) || (chan_sig == SIG_BRI_PTMP) || (chan_sig == SIG_SS7)) {
tmp->inservice = 0;
- else /* We default to in service on protocols that don't have a reset */
+ if (chan_sig == SIG_SS7 && tmp->ss7->flags & LINKSET_FLAG_INITIALHWBLO)
+ tmp->remotelyblocked |= SS7_BLOCKED_HARDWARE;
+ } else /* We default to in service on protocols that don't have a reset */
tmp->inservice = 1;
}
}
@@ -9064,7 +9299,7 @@
#ifdef HAVE_SS7
/* Trust SS7 */
if (p->ss7) {
- if (p->ss7call)
+ if (p->ss7call || !p->inservice)
return 0;
else
return 1;
@@ -9446,6 +9681,28 @@
return winner;
}
+static void ss7_check_range(struct dahdi_ss7 *linkset, int startcic, int endcic, unsigned int dpc, unsigned char *state)
+{
+ int cic;
+
+ for (cic = startcic; cic <= endcic; cic++)
+ if (state[cic - startcic] && ss7_find_cic(linkset, cic, dpc) == -1)
+ state[cic - startcic] = 0;
+}
+
+static int ss7_find_cic_range(struct dahdi_ss7 *linkset, int startcic, int endcic, unsigned int dpc)
+{
+ int x, found = 0;
+
+ for (x = 0; x < linkset->numchans; x++)
+ if (linkset->pvts[x] && (linkset->pvts[x]->dpc == dpc && linkset->pvts[x]->cic >= startcic && linkset->pvts[x]->cic <= endcic))
+ found++;
+ if (found == endcic - startcic + 1)
+ return 1;
+ else
+ return 0;
+}
+
static void ss7_handle_cqm(struct dahdi_ss7 *linkset, int startcic, int endcic, unsigned int dpc)
{
unsigned char status[32];
@@ -9478,33 +9735,52 @@
}
-static inline void ss7_hangup_cics(struct dahdi_ss7 *linkset, int startcic, int endcic, unsigned int dpc)
-{
- int i;
-
- for (i = 0; i < linkset->numchans; i++) {
- if (linkset->pvts[i] && (linkset->pvts[i]->dpc == dpc && ((linkset->pvts[i]->cic >= startcic) && (linkset->pvts[i]->cic <= endcic)))) {
- ast_mutex_lock(&linkset->pvts[i]->lock);
- if (linkset->pvts[i]->owner)
- linkset->pvts[i]->owner->_softhangup |= AST_SOFTHANGUP_DEV;
- ast_mutex_unlock(&linkset->pvts[i]->lock);
- }
- }
-}
-
-static inline void ss7_block_cics(struct dahdi_ss7 *linkset, int startcic, int endcic, unsigned int dpc, unsigned char state[], int block)
-{
- int i;
-
+static inline void ss7_block_cics(struct dahdi_ss7 *linkset, int startcic, int endcic, unsigned int dpc, unsigned char state[], int block, int remotely, int type)
+{
+ int i, offset = 0;
for (i = 0; i < linkset->numchans; i++) {
if (linkset->pvts[i] && (linkset->pvts[i]->dpc == dpc && ((linkset->pvts[i]->cic >= startcic) && (linkset->pvts[i]->cic <= endcic)))) {
if (state) {
- if (state[i])
- linkset->pvts[i]->remotelyblocked = block;
- } else
- linkset->pvts[i]->remotelyblocked = block;
- }
- }
+ if (state[offset]) {
+ if (linkset->pvts[i]->cic != startcic)
+ ast_mutex_lock(&linkset->pvts[i]->lock);
+
+ if (block) {
+ if (remotely)
+ linkset->pvts[i]->remotelyblocked |= type;
+ else
+ linkset->pvts[i]->locallyblocked |= type;
+ } else {
+ if (remotely)
+ linkset->pvts[i]->remotelyblocked &= ~type;
+ else
+ linkset->pvts[i]->locallyblocked &= ~type;
+ }
+
+ if (linkset->pvts[i]->owner && linkset->pvts[i]->owner->_state == AST_STATE_DIALING && !linkset->pvts[i]->proceeding) {
+ linkset->pvts[i]->owner->hangupcause = SS7_CAUSE_TRY_AGAIN;
+ linkset->pvts[i]->owner->_softhangup |= AST_SOFTHANGUP_DEV;
+ }
+
+ if (linkset->pvts[i]->cic != startcic)
+ ast_mutex_unlock(&linkset->pvts[i]->lock);
+ }
+ offset++;
+ } else {
+ if (block) {
+ if (remotely)
+ linkset->pvts[i]->remotelyblocked |= type;
+ else
+ linkset->pvts[i]->locallyblocked |= type;
+ } else {
+ if (remotely)
+ linkset->pvts[i]->remotelyblocked &= ~type;
+ else
+ linkset->pvts[i]->locallyblocked &= ~type;
+ }
+ }
+ }
+ } /* for */
}
static void ss7_inservice(struct dahdi_ss7 *linkset, int startcic, int endcic, unsigned int dpc)
@@ -9520,11 +9796,13 @@
static void ss7_reset_linkset(struct dahdi_ss7 *linkset)
{
int i, startcic = -1, endcic, dpc;
+ struct dahdi_pvt *p;
if (linkset->numchans <= 0)
return;
startcic = linkset->pvts[0]->cic;
+ p = linkset->pvts[0];
/* DB: CIC's DPC fix */
dpc = linkset->pvts[0]->dpc;
@@ -9534,12 +9812,16 @@
} else {
endcic = linkset->pvts[i]->cic;
ast_verbose("Resetting CICs %d to %d\n", startcic, endcic);
- isup_grs(linkset->ss7, startcic, endcic, dpc);
+ if (!ss7_find_alloc_call(p))
+ ast_log(LOG_ERROR, "Unable allocate new ss7call\n");
+ else
+ isup_grs(linkset->ss7, p->ss7call, endcic);
/* DB: CIC's DPC fix */
if (linkset->pvts[i+1]) {
startcic = linkset->pvts[i+1]->cic;
dpc = linkset->pvts[i+1]->dpc;
+ p = linkset->pvts[i+1];
}
}
}
@@ -9554,6 +9836,79 @@
}
p->loopedback = enable;
}
+}
+
+/* call me with locked p !!! */
+static int ss7_do_rsc(struct dahdi_pvt *p)
+{
+ if (!p || !p->ss7call)
+ return 0;
+
+ isup_rsc(p->ss7->ss7, p->ss7call);
+
+ if (p->locallyblocked == SS7_BLOCKED_MAINTENANCE)
+ isup_blo(p->ss7->ss7, p->ss7call);
+ else
+ p->locallyblocked = 0;
+
+ return 1;
+}
+
+/* call me with locked p !!! */
+static int ss7_start_rsc(struct dahdi_pvt *p)
+{
+ if (!p)
+ return 0;
+
+ if (!ss7_find_alloc_call(p))
+ return 0;
+
+ p->remotelyblocked = 0;
+ p->inservice = 0;
+ dahdi_loopback(p, 0);
+
+ if (p->owner) {
+ p->owner->hangupcause = AST_CAUSE_NORMAL_CLEARING;
+ p->owner->_softhangup |= AST_SOFTHANGUP_DEV;
+ p->do_hangup = SS7_HANGUP_SEND_RSC;
+ return 1;
+ } else
+ ss7_do_rsc(p);
+
+ return 1;
+}
+
+static int ss7_clear_channels(struct dahdi_pvt *p, int endcic, int do_hangup)
+{
+ int i, chanpos, clean = 1;
+ struct dahdi_pvt *p_cur;
+
+ if (!p || !p->ss7call)
+ return 0;
+
+ for (i = p->cic; i <= endcic; i++) {
+ chanpos = ss7_find_cic(p->ss7, i, p->dpc);
+ p_cur = p->ss7->pvts[chanpos];
+
+ if (p_cur != p)
+ ast_mutex_lock(&p_cur->lock);
+
+ p_cur->inservice = 0;
+
+ if (p_cur->owner) {
+ p_cur->owner->hangupcause = AST_CAUSE_NORMAL_CLEARING;
+ p_cur->owner->_softhangup |= AST_SOFTHANGUP_DEV;
+ p_cur->do_hangup = do_hangup;
+ clean = 0;
+ } else if (p_cur->ss7call && p != p_cur) {
+ isup_free_call(p_cur->ss7->ss7, p_cur->ss7call);
+ p_cur->ss7call = NULL;
+ }
+ if (p_cur != p)
+ ast_mutex_unlock(&p_cur->lock);
+ }
+
+ return clean;
}
/* XXX: This function is assumed to be called with the private channel lock and linkset lock held */
@@ -9564,6 +9919,7 @@
int law = 1;
struct ast_channel *c;
char tmp[256];
+ char *strp;
if (ioctl(p->subs[SUB_REAL].dfd, DAHDI_AUDIOMODE, &law) == -1)
ast_log(LOG_WARNING, "Unable to set audio mode on channel %d to %d: %s\n", p->channel, law, strerror(errno));
@@ -9583,12 +9939,13 @@
}
ast_mutex_unlock(&linkset->lock);
- c = dahdi_new(p, AST_STATE_RING, 1, SUB_REAL, law, 0);
+ c = dahdi_new(p, AST_STATE_RING, 0, SUB_REAL, law, 0); /* The startpbx is sometimes faster than we set up the variables!!! */
if (!c) {
ast_log(LOG_WARNING, "Unable to start PBX on CIC %d\n", p->cic);
/* Holding this lock is assumed entering the function */
ast_mutex_lock(&linkset->lock);
+ isup_rel(p->ss7->ss7, p->ss7call, AST_CAUSE_SWITCH_CONGESTION);
return;
} else
ast_verb(3, "Accepting call to '%s' on CIC %d\n", p->exten, p->cic);
@@ -9668,8 +10025,127 @@
/* Clear this after we set it */
p->generic_name[0] = 0;
}
-
+ if (p->redirect_counter) {
+ char redirect_counter_str[8];
+ sprintf(redirect_counter_str, "%u", p->redirect_counter);
+ pbx_builtin_setvar_helper(c, "SS7_REDIRECT_COUNTER", redirect_counter_str);
+ /* Clear this after we set it */
+ p->redirect_counter = 0;
+ }
+ if (p->redirect_info) {
+ switch (p->redirect_info_ind) {
+ case 0:
+ strp = "NO_REDIRECTION";
+ break;
+ case 1:
+ strp = "CALL_REROUTED_PRES_ALLOWED";
+ break;
+ case 2:
+ strp = "CALL_REROUTED_INFO_RESTRICTED";
+ break;
+ case 3:
+ strp = "CALL_DIVERTED_PRES_ALLOWED";
+ break;
+ case 4:
+ strp = "CALL_DIVERTED_INFO_RESTRICTED";
+ break;
+ case 5:
+ strp = "CALL_REROUTED_PRES_RESTRICTED";
+ break;
+ case 6:
+ strp = "CALL_DIVERTED_PRES_RESTRICTED";
+ break;
+ case 7:
+ strp = "SPARE";
+ break;
+ default:
+ strp = "NO_REDIRECTION";
+ }
+ pbx_builtin_setvar_helper(c, "SS7_REDIRECT_INFO_IND", strp);
+
+ switch (p->redirect_info_orig_reas) {
+ case 0:
+ strp = "UNKNOWN";
+ break;
+ case 1:
+ strp = "USER-BUSY";
+ break;
+ case 2:
+ strp = "NO-ANSWER";
+ break;
+ case 3:
+ strp = "UNCONDITIONAL";
+ break;
+ default:
+ strp = "UNKNOWN";
+ }
+ pbx_builtin_setvar_helper(c, "SS7_REDIRECT_INFO_ORIG_REAS", strp);
+
+ switch (p->redirect_info_reas) {
+ case 0:
+ strp = "UNKNOWN";
+ break;
+ case 1:
+ strp = "USER-BUSY";
+ break;
+ case 2:
+ strp = "NO-ANSWER";
+ break;
+ case 3:
+ strp = "UNCONDITIONAL";
+ break;
+ case 4:
+ strp = "DEFLECTION_DURING_ALERTING";
+ break;
+ case 5:
+ strp = "DEFLECTION_IMMEDIATE_RESPONSE";
+ break;
+ case 6:
+ strp = "UNAVAILABLE";
+ break;
+ default:
+ strp = "UNKNOWN";
+ break;
+ }
+ pbx_builtin_setvar_helper(c, "SS7_REDIRECT_INFO_REAS", strp);
+
+ snprintf(tmp, sizeof(tmp), "%d", p->redirect_info_counter);
+ pbx_builtin_setvar_helper(c, "SS7_REDIRECT_INFO_COUNTER", tmp);
+ }
+ if (p->cug_indicator != ISUP_CUG_NON) {
+ sprintf(tmp, "%d", p->cug_interlock_code);
+ pbx_builtin_setvar_helper(c, "SS7_CUG_INTERLOCK_CODE", tmp);
+
+ switch (p->cug_indicator) {
+ case ISUP_CUG_NON:
+ strp = "NON_CUG";
+ break;
+ case ISUP_CUG_OUTGOING_ALLOWED:
+ strp = "OUTGOING_ALLOWED";
+ break;
+ case ISUP_CUG_OUTGOING_NOT_ALLOWED:
+ strp = "OUTGOING_NOT_ALLOWED";
+ break;
+ default:
+ strp = "SPARE";
+ }
+ pbx_builtin_setvar_helper(c, "SS7_CUG_INDICATOR", strp);
+
+ if (p->cug_interlock_ni)
+ pbx_builtin_setvar_helper(c, "SS7_CUG_INTERLOCK_NI", p->cug_interlock_ni);
+
+ p->cug_indicator = ISUP_CUG_NON;
+ }
+
ast_mutex_lock(&p->lock);
+
+ /* STARTPBX !!! */
+ if (ast_pbx_start(c)) {
+ ast_log(LOG_WARNING, "Unable to start PBX on %s\n", c->name);
+ c->hangupcause = AST_CAUSE_SWITCH_CONGESTION; /* The ast_hangup() is dangerous here!!! */
+ c->_softhangup |= AST_SOFTHANGUP_DEV;
+ }
+
ast_mutex_lock(&linkset->lock);
}
@@ -9688,14 +10164,38 @@
case SS7_NAI_UNKNOWN:
snprintf(buf, size, "%s%s", ss7->unknownprefix, number);
break;
+ case SS7_NAI_NETWORKROUTED:
+ snprintf(buf, size, "%s%s", ss7->networkroutedprefix, number);
+ break;
default:
snprintf(buf, size, "%s", number);
break;
}
}
+
static int ss7_pres_scr2cid_pres(char presentation_ind, char screening_ind)
{
return ((presentation_ind & 0x3) << 5) | (screening_ind & 0x3);
+}
+
+static void ss7_process_connected(struct dahdi_pvt *p, char *connected_num, unsigned char connected_nai,
+ unsigned char connected_presentation_ind, unsigned char connected_screening_ind)
+{
+ struct ast_channel *c;
+ char buf[AST_MAX_EXTENSION];
+
+ if (!p->owner)
+ return;
+
+ c = p->owner;
+ if (!ast_strlen_zero(connected_num)) {
+ ss7_apply_plan_to_number(buf, sizeof(buf), p->ss7, connected_num, connected_nai);
+ pbx_builtin_setvar_helper(c, "SS7_CONNECTED_NUMBER", buf);
+ }
+
+ pbx_builtin_setvar_helper(c, "SS7_CONNECTED_PRES",
+ ast_named_caller_presentation(ss7_pres_scr2cid_pres(connected_presentation_ind, connected_screening_ind)));
+
}
static void *ss7_linkset(void *data)
@@ -9705,12 +10205,14 @@
struct dahdi_ss7 *linkset = (struct dahdi_ss7 *) data;
struct ss7 *ss7 = linkset->ss7;
ss7_event *e = NULL;
- struct dahdi_pvt *p;
+ struct dahdi_pvt *p_cur, *p = NULL; /* just shut up gcc 4.1 */
int chanpos;
struct pollfd pollers[NUM_DCHANS];
int cic;
unsigned int dpc;
+ unsigned char state[255], mb_state[255];
int nextms = 0;
+ int mbcount;
ss7_start(ss7);
@@ -9730,7 +10232,9 @@
}
nextms = tv.tv_sec * 1000;
nextms += tv.tv_usec / 1000;
- }
+ } else
+ nextms = -1;
+
ast_mutex_unlock(&linkset->lock);
for (i = 0; i < linkset->numsigchans; i++) {
@@ -9746,7 +10250,6 @@
ast_mutex_lock(&linkset->lock);
ss7_schedule_run(ss7);
ast_mutex_unlock(&linkset->lock);
- continue;
}
ast_mutex_lock(&linkset->lock);
@@ -9810,8 +10313,11 @@
linkset->state = LINKSET_STATE_DOWN;
for (i = 0; i < linkset->numchans; i++) {
struct dahdi_pvt *p = linkset->pvts[i];
- if (p)
- p->inalarm = 1;
+ if (p) {
+ p->inservice = 0;
+ if (linkset->flags & LINKSET_FLAG_INITIALHWBLO)
+ p->remotelyblocked |= SS7_BLOCKED_HARDWARE;
+ }
}
break;
case MTP2_LINK_UP:
@@ -9822,12 +10328,14 @@
break;
case ISUP_EVENT_CPG:
chanpos = ss7_find_cic(linkset, e->cpg.cic, e->cpg.opc);
- if (chanpos < 0) {
- ast_log(LOG_WARNING, "CPG on unconfigured CIC %d\n", e->cpg.cic);
+ if (chanpos < 0) { /* Never will be true */
+ ast_log(LOG_WARNING, "CPG on unconfigured CIC %d PC %d\n", e->cpg.cic, e->cpg.opc);
+ isup_free_call(ss7, e->cpg.call);
break;
}
p = linkset->pvts[chanpos];
ast_mutex_lock(&p->lock);
+
switch (e->cpg.event) {
case CPG_EVENT_ALERTING:
p->alerting = 1;
@@ -9841,8 +10349,8 @@
dahdi_queue_frame(p, &f, linkset);
p->progress = 1;
if (p->dsp && p->dsp_features) {
- ast_dsp_set_features(p->dsp, p->dsp_features);
- p->dsp_features = 0;
+ ast_dsp_set_features(p->dsp, p->dsp_features);
+ p->dsp_features = 0;
}
}
break;
@@ -9856,63 +10364,190 @@
ast_verbose("Resetting CIC %d\n", e->rsc.cic);
chanpos = ss7_find_cic(linkset, e->rsc.cic, e->rsc.opc);
if (chanpos < 0) {
- ast_log(LOG_WARNING, "RSC on unconfigured CIC %d\n", e->rsc.cic);
+ ast_log(LOG_WARNING, "RSC on unconfigured CIC %d PC %d\n", e->rsc.cic, e->rsc.opc);
+ isup_free_call(ss7, e->rsc.call);
break;
}
p = linkset->pvts[chanpos];
ast_mutex_lock(&p->lock);
+ p->ss7call = e->rsc.call;
p->inservice = 1;
p->remotelyblocked = 0;
dpc = p->dpc;
+ if (p->locallyblocked == SS7_BLOCKED_MAINTENANCE)
+ isup_blo(ss7, e->rsc.call);
+ else if (p->locallyblocked == SS7_BLOCKED_HARDWARE)
+ p->locallyblocked = 0;
+
isup_set_call_dpc(e->rsc.call, dpc);
- if (p->ss7call)
- p->ss7call = NULL;
- if (p->owner)
+
+ if (p->owner) {
p->owner->_softhangup |= AST_SOFTHANGUP_DEV;
+ p->do_hangup = SS7_HANGUP_SEND_RLC;
+ if (e->rsc.got_sent_msg != ISUP_SENT_IAM) {
+ /* Q.784 6.2.3 */
+ p->owner->hangupcause = AST_CAUSE_NORMAL_CLEARING;
+ } else {
+ p->owner->hangupcause = SS7_CAUSE_TRY_AGAIN;
+ }
+ } else {
+ isup_rlc(ss7, e->rsc.call);
+ p->ss7call = isup_free_call_if_clear(ss7, e->rsc.call);
+ }
+ /* End the loopback if we have one */
+ dahdi_loopback(p, 0);
ast_mutex_unlock(&p->lock);
- isup_rlc(ss7, e->rsc.call);
break;
case ISUP_EVENT_GRS:
- ast_debug(1, "Got Reset for CICs %d to %d: Acknowledging\n", e->grs.startcic, e->grs.endcic);
+ if (!ss7_find_cic_range(linkset, e->grs.startcic, e->grs.endcic, e->grs.opc)) {
+ ast_log(LOG_WARNING, "GRS on unconfigured range CIC %d - %d PC %d\n", e->grs.startcic, e->grs.endcic, e->grs.opc);
+ chanpos = ss7_find_cic(linkset, e->grs.startcic, e->grs.opc);
+ if (chanpos > -1) {
+ p = linkset->pvts[chanpos];
+ ast_mutex_lock(&p->lock);
+ p->ss7call = isup_free_call_if_clear(ss7, e->grs.call);
+ ast_mutex_unlock(&p->lock);
+ } else
+ isup_free_call(ss7, e->grs.call);
+ break;
+ }
+
chanpos = ss7_find_cic(linkset, e->grs.startcic, e->grs.opc);
- if (chanpos < 0) {
- ast_log(LOG_WARNING, "GRS on unconfigured CIC %d\n", e->grs.startcic);
- break;
- }
p = linkset->pvts[chanpos];
- isup_gra(ss7, e->grs.startcic, e->grs.endcic, e->grs.opc);
- ss7_block_cics(linkset, e->grs.startcic, e->grs.endcic, e->grs.opc, NULL, 0);
- ss7_hangup_cics(linkset, e->grs.startcic, e->grs.endcic, e->grs.opc);
+ ast_mutex_lock(&p->lock);
+ p->ss7call = e->grs.call;
+
+ ss7_block_cics(linkset, e->grs.startcic, e->grs.endcic, e->grs.opc, NULL, 0, 1,
+ SS7_BLOCKED_MAINTENANCE | SS7_BLOCKED_HARDWARE);
+
+ mbcount = 0;
+ for (i = 0; i <= e->grs.endcic - p->cic; i++) {
+ chanpos = ss7_find_cic(p->ss7, i + p->cic, p->dpc);
+ p_cur = p->ss7->pvts[chanpos];
+ if (p != p_cur)
+ ast_mutex_lock(&p_cur->lock);
+
+ if (p_cur->locallyblocked & SS7_BLOCKED_HARDWARE)
+ state[i] = 1;
+ else
+ state[i] = 0;
+
+ if (p_cur->locallyblocked & SS7_BLOCKED_MAINTENANCE) {
+ mb_state[i] = 1;
+ mbcount++;
+ } else
+ mb_state[i] = 0;
+
+ if (p_cur->owner) {
+ p_cur->owner->_softhangup |= AST_SOFTHANGUP_DEV;
+ if (p_cur->owner->_state == AST_STATE_DIALING && !linkset->pvts[i]->proceeding)
+ p_cur->owner->hangupcause = SS7_CAUSE_TRY_AGAIN;
+ else
+ p_cur->owner->hangupcause = AST_CAUSE_NORMAL_CLEARING;
+ p_cur->do_hangup = SS7_HANGUP_FREE_CALL;
+ } else if (p->ss7call && p != p_cur) { /* clear any session */
+ isup_free_call(ss7, p_cur->ss7call);
+ p_cur->ss7call = NULL;
+ }
+
+ p_cur->inservice = 1;
+
+ if (p != p_cur)
+ ast_mutex_unlock(&p_cur->lock);
+ }
+
+ if (mbcount)
+ isup_cgb(ss7, p->ss7call, e->grs.endcic, mb_state, 0);
+
+ isup_gra(ss7, p->ss7call, e->grs.endcic, state);
+ if (!p->owner)
+ p->ss7call = isup_free_call_if_clear(ss7, p->ss7call);
+ ast_mutex_unlock(&p->lock);
break;
case ISUP_EVENT_CQM:
ast_debug(1, "Got Circuit group query message from CICs %d to %d\n", e->cqm.startcic, e->cqm.endcic);
ss7_handle_cqm(linkset, e->cqm.startcic, e->cqm.endcic, e->cqm.opc);
+ chanpos = ss7_find_cic(linkset, e->iam.cic, e->iam.opc);
+ if (chanpos > -1) {
+ p = linkset->pvts[chanpos];
+ ast_mutex_lock(&p->lock);
+ if (!p->owner)
+ p->ss7call = isup_free_call_if_clear(ss7, e->cqm.call);
+ ast_mutex_unlock(&p->lock);
+ }
break;
case ISUP_EVENT_GRA:
- ast_verbose("Got reset acknowledgement from CIC %d to %d.\n", e->gra.startcic, e->gra.endcic);
- ss7_inservice(linkset, e->gra.startcic, e->gra.endcic, e->gra.opc);
- ss7_block_cics(linkset, e->gra.startcic, e->gra.endcic, e->gra.opc, e->gra.status, 1);
+ if (!ss7_find_cic_range(linkset, e->gra.startcic, e->gra.endcic, e->gra.opc)) { /* Never will be true */
+ ast_log(LOG_WARNING, "GRA on unconfigured range CIC %d - %d PC %d\n", e->gra.startcic, e->gra.endcic, e->gra.opc);
+ isup_free_call(ss7, e->gra.call);
+ break;
+ }
+ chanpos = ss7_find_cic(linkset, e->gra.startcic, e->gra.opc);
+ p = linkset->pvts[chanpos];
+ ast_mutex_lock(&p->lock);
+ p->ss7call = e->gra.call;
+
+ ast_verbose("Got reset acknowledgement from CIC %d to %d DPC: %d\n", e->gra.startcic, e->gra.endcic, e->gra.opc);
+ ss7_inservice(linkset, e->gra.startcic, e->gra.endcic, e->gra.opc);
+ ss7_block_cics(linkset, e->gra.startcic, e->gra.endcic, e->gra.opc, e->gra.status,
+ 1, 1, SS7_BLOCKED_HARDWARE);
+
+ p->ss7call = isup_free_call_if_clear(ss7, p->ss7call); /* we may sent a CDB with GRS! */
+ ast_mutex_unlock(&p->lock);
break;
+ case ISUP_EVENT_SAM:
+ chanpos = ss7_find_cic(linkset, e->sam.cic, e->sam.opc);
+ if (chanpos < 0) {
+ ast_log(LOG_WARNING, "SAM on unconfigured CIC %d PC %d\n", e->sam.cic, e->sam.opc);
+ isup_free_call(ss7, e->sam.call);
+ break;
+ }
+ p = linkset->pvts[chanpos];
+ ast_mutex_lock(&p->lock);
+ if (p->owner) {
+ ast_log(LOG_WARNING, "SAM on CIC %d PC %d already have call\n", e->sam.cic, e->sam.opc);
+ ast_mutex_unlock(&p->lock);
+ break;
+ }
+ p->called_complete = 0;
+ if (!ast_strlen_zero(e->sam.called_party_num)) {
+ char *st;
+ strncat(p->exten, e->sam.called_party_num, sizeof(p->exten) - strlen(p->exten));
+ st = strchr(p->exten, '#');
+ if (st) {
+ *st = '\0';
+ p->called_complete = 1;
+ }
+ } else
+ p->exten[0] = '\0';
+ goto ss7_start_switch;
case ISUP_EVENT_IAM:
ast_debug(1, "Got IAM for CIC %d and called number %s, calling number %s\n", e->iam.cic, e->iam.called_party_num, e->iam.calling_party_num);
chanpos = ss7_find_cic(linkset, e->iam.cic, e->iam.opc);
if (chanpos < 0) {
- ast_log(LOG_WARNING, "IAM on unconfigured CIC %d\n", e->iam.cic);
- isup_rel(ss7, e->iam.call, -1);
+ ast_log(LOG_WARNING, "IAM on unconfigured CIC %d PC %d\n", e->iam.cic, e->iam.opc);
+ isup_free_call(ss7, e->iam.call);
break;
}
p = linkset->pvts[chanpos];
ast_mutex_lock(&p->lock);
+ p->ss7call = e->iam.call;
+ if (p->locallyblocked) {
[... 2295 lines stripped ...]
More information about the asterisk-commits
mailing list