[asterisk-commits] rmudgett: branch rmudgett/sig_ss7 r261099 - /team/rmudgett/sig_ss7/channels/
SVN commits to the Asterisk project
asterisk-commits at lists.digium.com
Tue May 4 19:14:35 CDT 2010
Author: rmudgett
Date: Tue May 4 19:14:31 2010
New Revision: 261099
URL: http://svnview.digium.com/svn/asterisk?view=rev&rev=261099
Log:
Today's progress through the SS7 extraction swamp.
Modified:
team/rmudgett/sig_ss7/channels/chan_dahdi.c
team/rmudgett/sig_ss7/channels/sig_ss7.h
Modified: team/rmudgett/sig_ss7/channels/chan_dahdi.c
URL: http://svnview.digium.com/svn/asterisk/team/rmudgett/sig_ss7/channels/chan_dahdi.c?view=diff&rev=261099&r1=261098&r2=261099
==============================================================================
--- team/rmudgett/sig_ss7/channels/chan_dahdi.c (original)
+++ team/rmudgett/sig_ss7/channels/chan_dahdi.c Tue May 4 19:14:31 2010
@@ -515,6 +515,42 @@
#ifdef HAVE_SS7
/* BUGBUG sig_ss7 callback functions ----v*/
+#define SIG_SS7_DEADLOCK_AVOIDANCE(p) \
+ do { \
+ sig_ss7_unlock_private(p); \
+ usleep(1); \
+ sig_ss7_lock_private(p); \
+ } while (0)
+
+static void sig_ss7_unlock_private(struct sig_ss7_chan *p)
+{
+ if (p->calls->unlock_private) {
+ p->calls->unlock_private(p->chan_pvt);
+ }
+}
+
+static void sig_ss7_lock_private(struct sig_ss7_chan *p)
+{
+ if (p->calls->lock_private) {
+ p->calls->lock_private(p->chan_pvt);
+ }
+}
+
+void sig_ss7_set_alarm(struct sig_ss7_chan *p, int in_alarm)
+{
+ p->inalarm = in_alarm;
+ if (p->calls->set_alarm) {
+ p->calls->set_alarm(p->chan_pvt, in_alarm);
+ }
+}
+
+static void sig_ss7_set_dialing(struct sig_ss7_chan *p, int is_dialing)
+{
+ if (p->calls->set_dialing) {
+ p->calls->set_dialing(p->chan_pvt, is_dialing);
+ }
+}
+
/*!
* \internal
* \brief Set the caller id information in the parent module.
@@ -583,18 +619,12 @@
}
}
-static void sig_ss7_unlock_private(struct sig_ss7_chan *p)
-{
- if (p->calls->unlock_private) {
- p->calls->unlock_private(p->chan_pvt);
- }
-}
-
-static void sig_ss7_lock_private(struct sig_ss7_chan *p)
-{
- if (p->calls->lock_private) {
- p->calls->lock_private(p->chan_pvt);
- }
+static int sig_ss7_set_echocanceller(struct sig_ss7_chan *p, int enable)
+{
+ if (p->calls->set_echocanceller) {
+ return p->calls->set_echocanceller(p->chan_pvt, enable);
+ }
+ return -1;
}
static void sig_ss7_loopback(struct sig_ss7_chan *p, int enable)
@@ -606,6 +636,7 @@
}
}
}
+
/* BUGBUG sig_ss7 callback functions ----^*/
struct dahdi_ss7 {
@@ -1046,24 +1077,6 @@
struct sig_pri_pri *pri;
int logicalspan;
#endif
-#if defined(HAVE_PRI) || defined(HAVE_SS7)
- /*!
- * \brief XXX BOOLEAN Purpose???
- * \note Applies to SS7 channels.
- */
- unsigned int rlt:1;
- /*! \brief TRUE if channel is alerting/ringing */
- unsigned int alerting:1;
- /*! \brief TRUE if the call has already gone/hungup */
- unsigned int alreadyhungup:1;
- /*!
- * \brief TRUE if call is in a proceeding state.
- * The call has started working its way through the network.
- */
- unsigned int proceeding:1;
- /*! \brief TRUE if the call has seen progress through the network. */
- unsigned int progress:1;
-#endif
/*!
* \brief TRUE if SMDI (Simplified Message Desk Interface) is enabled
* \note Set from the "usesmdi" value read in from chan_dahdi.conf
@@ -3186,6 +3199,7 @@
.new_ast_channel = my_new_ss7_ast_channel,
.play_tone = my_ss7_play_tone,
+ .set_alarm = my_set_alarm,
.set_dialing = my_set_dialing,
.set_callerid = my_set_callerid,
.set_dnid = my_set_dnid,
@@ -3334,14 +3348,14 @@
#endif /* defined(HAVE_SS7) */
#if defined(HAVE_SS7)
-static inline int ss7_grab(struct dahdi_pvt *pvt, struct sig_ss7_linkset *ss7)
+static inline int ss7_grab(struct sig_ss7_chan *pvt, struct sig_ss7_linkset *ss7)
{
int res;
/* Grab the lock first */
do {
res = ast_mutex_trylock(&ss7->lock);
if (res) {
- DEADLOCK_AVOIDANCE(&pvt->lock);
+ SIG_SS7_DEADLOCK_AVOIDANCE(pvt);
}
} while (res);
/* Then break the poll */
@@ -3384,21 +3398,28 @@
}
}
-static void dahdi_queue_frame(struct dahdi_pvt *p, struct ast_frame *f, void *data)
-{
-#ifdef HAVE_SS7
- struct dahdi_ss7 *ss7 = (struct dahdi_ss7*) data;
-
- if (data) {
- switch (p->sig) {
- case SIG_SS7:
- ast_mutex_unlock(&ss7->ss7.lock);
+/* BUGBUG move to sig_ss7.c */
+static void sig_ss7_queue_frame(struct sig_ss7_chan *p, struct ast_frame *f, struct sig_ss7_linkset *ss7)
+{
+ /* We must unlock the SS7 to avoid the possibility of a deadlock */
+ ast_mutex_unlock(&ss7->lock);
+ for (;;) {
+ if (p->owner) {
+ if (ast_channel_trylock(p->owner)) {
+ SIG_SS7_DEADLOCK_AVOIDANCE(p);
+ } else {
+ ast_queue_frame(p->owner, f);
+ ast_channel_unlock(p->owner);
+ break;
+ }
+ } else
break;
- default:
- break;
- }
- }
-#endif
+ }
+ ast_mutex_lock(&ss7->lock);
+}
+
+static void dahdi_queue_frame(struct dahdi_pvt *p, struct ast_frame *f)
+{
for (;;) {
if (p->owner) {
if (ast_channel_trylock(p->owner)) {
@@ -3411,17 +3432,6 @@
} else
break;
}
-#if defined(HAVE_SS7)
- if (data) {
- switch (p->sig) {
- case SIG_SS7:
- ast_mutex_lock(&ss7->ss7.lock);
- break;
- default:
- break;
- }
- }
-#endif
}
static void handle_clear_alarms(struct dahdi_pvt *p)
@@ -4980,9 +4990,7 @@
struct dahdi_pvt *p = ast->tech_pvt;
int x, res, mysig;
char dest[256]; /* must be same length as p->dialdest */
-#ifdef HAVE_SS7
- char *c, *l;
-#endif
+
ast_mutex_lock(&p->lock);
ast_copy_string(dest, rdest, sizeof(dest));
ast_copy_string(p->dialdest, rdest, sizeof(p->dialdest));
@@ -5031,6 +5039,15 @@
}
#endif
+#if defined(HAVE_SS7)
+ if (p->sig == SIG_SS7) {
+ p->digital = IS_DIGITAL(ast->transfercapability);
+ res = sig_ss7_call(p->sig_pvt, ast, rdest);
+ ast_mutex_unlock(&p->lock);
+ return res;
+ }
+#endif /* defined(HAVE_SS7) */
+
/* If this is analog signalling we can exit here */
if (analog_lib_handles(p->sig, p->radio, p->oprmode)) {
p->callwaitrings = 0;
@@ -5045,11 +5062,7 @@
/* Special pseudo -- automatically up*/
ast_setstate(ast, AST_STATE_UP);
break;
- case SIG_SS7:
case SIG_MFCR2:
- /* We'll get it in a moment -- but use dialdest to store pre-setup_ack digits */
- p->dialdest[0] = '\0';
- p->dialing = 1;
break;
default:
ast_debug(1, "not yet implemented\n");
@@ -5057,24 +5070,14 @@
return -1;
}
-#if defined(HAVE_SS7)
- if (p->ss7) {
- char ss7_called_nai;
- int called_nai_strip;
- char ss7_calling_nai;
- int calling_nai_strip;
- const char *charge_str = NULL;
- const char *gen_address = NULL;
- const char *gen_digits = NULL;
- const char *gen_dig_type = NULL;
- const char *gen_dig_scheme = NULL;
- const char *gen_name = NULL;
- const char *jip_digits = NULL;
- const char *lspi_ident = NULL;
- const char *rlt_flag = NULL;
- const char *call_ref_id = NULL;
- const char *call_ref_pc = NULL;
- const char *send_far = NULL;
+#ifdef HAVE_OPENR2
+ if (p->mfcr2) {
+ openr2_calling_party_category_t chancat;
+ int callres = 0;
+ char *c, *l;
+
+ /* We'll get it in a moment -- but use dialdest to store pre-setup_ack digits */
+ p->dialdest[0] = '\0';
c = strchr(dest, '/');
if (c) {
@@ -5082,146 +5085,18 @@
} else {
c = "";
}
+ if (!p->hidecallerid) {
+ l = ast->cid.cid_num;
+ } else {
+ l = NULL;
+ }
if (strlen(c) < p->stripmsd) {
ast_log(LOG_WARNING, "Number '%s' is shorter than stripmsd (%d)\n", c, p->stripmsd);
ast_mutex_unlock(&p->lock);
return -1;
}
-
- if (!p->hidecallerid) {
- l = ast->connected.id.number;
- } else {
- l = NULL;
- }
-
- if (ss7_grab(p, p->ss7)) {
- ast_log(LOG_WARNING, "Failed to grab SS7!\n");
- ast_mutex_unlock(&p->lock);
- return -1;
- }
- p->digital = IS_DIGITAL(ast->transfercapability);
- p->ss7call = isup_new_call(p->ss7->ss7);
-
- if (!p->ss7call) {
- ss7_rel(p->ss7);
- ast_mutex_unlock(&p->lock);
- ast_log(LOG_ERROR, "Unable to allocate new SS7 call!\n");
- return -1;
- }
-
- 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;
- }
- }
- 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->connected.id.number_presentation) : (l ? SS7_PRESENTATION_ALLOWED : SS7_PRESENTATION_RESTRICTED),
- p->use_callingpres ? cid_pres2ss7screen(ast->connected.id.number_presentation) : SS7_SCREENING_USER_PROVIDED );
-
- isup_set_oli(p->ss7call, ast->connected.ani2);
- isup_init_call(p->ss7->ss7, p->ss7call, p->cic, p->dpc);
-
- ast_channel_lock(ast);
- /* Set the charge number if it is set */
- charge_str = pbx_builtin_getvar_helper(ast, "SS7_CHARGE_NUMBER");
- if (charge_str)
- isup_set_charge(p->ss7call, charge_str, SS7_ANI_CALLING_PARTY_SUB_NUMBER, 0x10);
-
- gen_address = pbx_builtin_getvar_helper(ast, "SS7_GENERIC_ADDRESS");
- if (gen_address)
- isup_set_gen_address(p->ss7call, gen_address, p->gen_add_nai,p->gen_add_pres_ind, p->gen_add_num_plan,p->gen_add_type); /* need to add some types here for NAI,PRES,TYPE */
-
- gen_digits = pbx_builtin_getvar_helper(ast, "SS7_GENERIC_DIGITS");
- gen_dig_type = pbx_builtin_getvar_helper(ast, "SS7_GENERIC_DIGTYPE");
- gen_dig_scheme = pbx_builtin_getvar_helper(ast, "SS7_GENERIC_DIGSCHEME");
- if (gen_digits)
- isup_set_gen_digits(p->ss7call, gen_digits, atoi(gen_dig_type), atoi(gen_dig_scheme));
-
- gen_name = pbx_builtin_getvar_helper(ast, "SS7_GENERIC_NAME");
- if (gen_name)
- isup_set_generic_name(p->ss7call, gen_name, GEN_NAME_TYPE_CALLING_NAME, GEN_NAME_AVAIL_AVAILABLE, GEN_NAME_PRES_ALLOWED);
-
- jip_digits = pbx_builtin_getvar_helper(ast, "SS7_JIP");
- if (jip_digits)
- isup_set_jip_digits(p->ss7call, jip_digits);
-
- lspi_ident = pbx_builtin_getvar_helper(ast, "SS7_LSPI_IDENT");
- if (lspi_ident)
- isup_set_lspi(p->ss7call, lspi_ident, 0x18, 0x7, 0x00);
-
- rlt_flag = pbx_builtin_getvar_helper(ast, "SS7_RLT_ON");
- if ((rlt_flag) && ((strncmp("NO", rlt_flag, strlen(rlt_flag))) != 0 )) {
- isup_set_lspi(p->ss7call, rlt_flag, 0x18, 0x7, 0x00); /* Setting for Nortel DMS-250/500 */
- }
-
- call_ref_id = pbx_builtin_getvar_helper(ast, "SS7_CALLREF_IDENT");
- call_ref_pc = pbx_builtin_getvar_helper(ast, "SS7_CALLREF_PC");
- if (call_ref_id && call_ref_pc) {
- isup_set_callref(p->ss7call, atoi(call_ref_id),
- call_ref_pc ? atoi(call_ref_pc) : 0);
- }
-
- 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));
-
- ast_channel_unlock(ast);
-
- isup_iam(p->ss7->ss7, p->ss7call);
- ast_setstate(ast, AST_STATE_DIALING);
- ss7_rel(p->ss7);
- }
-#endif /* defined(HAVE_SS7) */
-
-#ifdef HAVE_OPENR2
- if (p->mfcr2) {
- openr2_calling_party_category_t chancat;
- int callres = 0;
- char *c, *l;
-
- c = strchr(dest, '/');
- if (c) {
- c++;
- } else {
- c = "";
- }
- if (!p->hidecallerid) {
- l = ast->cid.cid_num;
- } else {
- l = NULL;
- }
- if (strlen(c) < p->stripmsd) {
- ast_log(LOG_WARNING, "Number '%s' is shorter than stripmsd (%d)\n", c, p->stripmsd);
- ast_mutex_unlock(&p->lock);
- return -1;
- }
p->dialing = 1;
- ast_channel_lock(ast);
chancat = dahdi_r2_get_channel_category(ast);
- ast_channel_unlock(ast);
callres = openr2_chan_make_call(p->r2chan, l, (c + p->stripmsd), chancat);
if (-1 == callres) {
ast_mutex_unlock(&p->lock);
@@ -5869,9 +5744,8 @@
return 0;
}
+ ast_mutex_lock(&p->lock);
if (analog_lib_handles(p->sig, p->radio, p->oprmode)) {
- ast_mutex_lock(&p->lock);
-
dahdi_confmute(p, 0);
restore_gains(p);
p->ignoredtmf = 0;
@@ -5887,22 +5761,18 @@
p->cid_subaddr[0] = '\0';
}
- ast_mutex_lock(&p->lock);
-
- idx = dahdi_get_index(ast, p, 1);
-
#ifdef HAVE_PRI
if (dahdi_sig_pri_lib_handles(p->sig)) {
- int law;
-
x = 1;
ast_channel_setoption(ast,AST_OPTION_AUDIO_MODE,&x,sizeof(char),0);
dahdi_confmute(p, 0);
+ p->muting = 0;
restore_gains(p);
if (p->dsp) {
ast_dsp_free(p->dsp);
p->dsp = NULL;
}
+ p->ignoredtmf = 0;
revert_fax_buffers(p, ast);
dahdi_setlinear(p->subs[SUB_REAL].dfd, 0);
law = DAHDI_LAW_DEFAULT;
@@ -5920,19 +5790,73 @@
p->digital = 0;
p->faxhandled = 0;
p->pulsedial = 0;/* Probably not used in this mode. Reset anyway. */
- //p->proceeding = 0;
- //p->progress = 0;
- //p->alerting = 0;
goto hangup_out;
}
#endif
+#if defined(HAVE_SS7)
if (p->sig == SIG_SS7) {
x = 1;
ast_channel_setoption(ast,AST_OPTION_AUDIO_MODE,&x,sizeof(char),0);
- }
-
- x = 0;
+
+ dahdi_confmute(p, 0);
+ p->muting = 0;
+ restore_gains(p);
+ if (p->dsp) {
+ ast_dsp_free(p->dsp);
+ p->dsp = NULL;
+ }
+ p->ignoredtmf = 0;
+
+ /* Real channel, do some fixup */
+ p->subs[SUB_REAL].owner = NULL;
+ p->subs[SUB_REAL].needanswer = 0;
+ p->subs[SUB_REAL].needringing = 0;
+ p->subs[SUB_REAL].needbusy = 0;
+ p->polarity = POLARITY_IDLE;
+ dahdi_setlinear(p->subs[SUB_REAL].dfd, 0);
+
+ p->owner = NULL;
+ p->ringt = 0;/* Probably not used in this mode. Reset anyway. */
+ p->distinctivering = 0;/* Probably not used in this mode. Reset anyway. */
+ p->confirmanswer = 0;/* Probably not used in this mode. Reset anyway. */
+ p->outgoing = 0;
+ p->digital = 0;
+ p->faxhandled = 0;
+ p->pulsedial = 0;/* Probably not used in this mode. Reset anyway. */
+
+ revert_fax_buffers(p, ast);
+
+ law = DAHDI_LAW_DEFAULT;
+ res = ioctl(p->subs[SUB_REAL].dfd, DAHDI_SETLAW, &law);
+ if (res < 0)
+ ast_log(LOG_WARNING, "Unable to set law on channel %d to default: %s\n", p->channel, strerror(errno));
+
+ sig_ss7_hangup(p->sig_pvt, ast);
+
+ tone_zone_play_tone(p->subs[SUB_REAL].dfd, -1);
+ dahdi_disable_ec(p);
+ x = 0;
+ ast_channel_setoption(ast,AST_OPTION_TONE_VERIFY,&x,sizeof(char),0);
+ ast_channel_setoption(ast,AST_OPTION_TDD,&x,sizeof(char),0);
+ p->didtdd = 0;/* Probably not used in this mode. Reset anyway. */
+ update_conf(p);
+ reset_conf(p);
+
+ /* Restore data mode */
+ x = 0;
+ ast_channel_setoption(ast,AST_OPTION_AUDIO_MODE,&x,sizeof(char),0);
+
+ if (num_restart_pending == 0)
+ restart_monitor();
+
+ ast->tech_pvt = NULL;
+ goto hangup_out;
+ }
+#endif /* defined(HAVE_SS7) */
+
+ idx = dahdi_get_index(ast, p, 1);
+
dahdi_confmute(p, 0);
p->muting = 0;
restore_gains(p);
@@ -6062,13 +5986,6 @@
p->digital = 0;
p->faxhandled = 0;
p->pulsedial = 0;
-#if defined(HAVE_PRI) || defined(HAVE_SS7)
- p->proceeding = 0;
- p->dialing = 0;
- p->progress = 0;
- p->alerting = 0;
- p->rlt = 0;
-#endif
if (p->dsp) {
ast_dsp_free(p->dsp);
p->dsp = NULL;
@@ -6081,30 +5998,6 @@
if (res < 0)
ast_log(LOG_WARNING, "Unable to set law on channel %d to default: %s\n", p->channel, strerror(errno));
/* Perform low level hangup if no owner left */
-#ifdef HAVE_SS7
- if (p->ss7) {
- if (p->ss7call) {
- if (!ss7_grab(p, p->ss7)) {
- if (!p->alreadyhungup) {
- const char *cause = pbx_builtin_getvar_helper(ast,"SS7_CAUSE");
- int icause = ast->hangupcause ? ast->hangupcause : -1;
-
- if (cause) {
- if (atoi(cause))
- icause = atoi(cause);
- }
- 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");
- } else {
- ast_log(LOG_WARNING, "Unable to grab SS7 on CIC %d\n", p->cic);
- res = -1;
- }
- }
- }
-#endif
#ifdef HAVE_OPENR2
if (p->mfcr2 && p->mfcr2call && openr2_chan_get_direction(p->r2chan) != OR2_DIR_STOPPED) {
ast_log(LOG_DEBUG, "disconnecting MFC/R2 call on chan %d\n", p->channel);
@@ -7591,6 +7484,11 @@
sig_pri_chan_alarm_notify(p->sig_pvt, 0);
break;
#endif /* defined(HAVE_PRI) */
+#if defined(HAVE_SS7)
+ case SIG_SS7:
+ sig_ss7_set_alarm(p->sig_pvt, 1);
+ break;
+#endif /* defined(HAVE_SS7) */
default:
p->inalarm = 1;
break;
@@ -7923,6 +7821,11 @@
sig_pri_chan_alarm_notify(p->sig_pvt, 1);
break;
#endif /* defined(HAVE_PRI) */
+#if defined(HAVE_SS7)
+ case SIG_SS7:
+ sig_ss7_set_alarm(p->sig_pvt, 0);
+ break;
+#endif /* defined(HAVE_SS7) */
default:
p->inalarm = 0;
break;
@@ -10928,6 +10831,11 @@
sig_pri_chan_alarm_notify(i->sig_pvt, 1);
break;
#endif /* defined(HAVE_PRI) */
+#if defined(HAVE_SS7)
+ case SIG_SS7:
+ sig_ss7_set_alarm(i->sig_pvt, 0);
+ break;
+#endif /* defined(HAVE_SS7) */
default:
i->inalarm = 0;
break;
@@ -10941,6 +10849,11 @@
sig_pri_chan_alarm_notify(i->sig_pvt, 0);
break;
#endif /* defined(HAVE_PRI) */
+#if defined(HAVE_SS7)
+ case SIG_SS7:
+ sig_ss7_set_alarm(i->sig_pvt, 1);
+ break;
+#endif /* defined(HAVE_SS7) */
default:
i->inalarm = 1;
break;
@@ -12242,6 +12155,11 @@
sig_pri_chan_alarm_notify(tmp->sig_pvt, si.alarms);
break;
#endif
+#if defined(HAVE_SS7)
+ case SIG_SS7:
+ sig_ss7_set_alarm(tmp->sig_pvt, 1);
+ break;
+#endif /* defined(HAVE_SS7) */
default:
tmp->inalarm = 1;
break;
@@ -12430,14 +12348,18 @@
if (analog_lib_handles(p->sig, p->radio, p->oprmode))
return analog_available(p->sig_pvt);
-#ifdef HAVE_PRI
switch (p->sig) {
+#if defined(HAVE_PRI)
case SIG_PRI_LIB_HANDLE_CASES:
return sig_pri_available(p->sig_pvt);
+#endif /* defined(HAVE_PRI) */
+#if defined(HAVE_SS7)
+ case SIG_SS7:
+ return sig_ss7_available(p->sig_pvt);
+#endif /* defined(HAVE_SS7) */
default:
break;
}
-#endif
if (p->locallyblocked || p->remotelyblocked) {
return 0;
@@ -12445,16 +12367,6 @@
/* If no owner definitely available */
if (!p->owner) {
-#ifdef HAVE_SS7
- /* Trust SS7 */
- if (p->ss7) {
- if (p->ss7call) {
- return 0;
- } else {
- return 1;
- }
- }
-#endif
#ifdef HAVE_OPENR2
/* Trust MFC/R2 */
if (p->mfcr2) {
@@ -13211,7 +13123,7 @@
} else
ast_verb(3, "Accepting call to '%s' on CIC %d\n", p->exten, p->cic);
- dahdi_enable_ec(p);
+ sig_ss7_set_echocanceller(p, 1);
/* We only reference these variables in the context of the ss7_linkset function
* when receiving either and IAM or a COT message. Since they are only accessed
@@ -13442,9 +13354,10 @@
ast_verbose("--- SS7 Down ---\n");
linkset->state = LINKSET_STATE_DOWN;
for (i = 0; i < linkset->numchans; i++) {
- struct dahdi_pvt *p = linkset->pvts[i];
- if (p)
- p->inalarm = 1;
+ p = linkset->pvts[i];
+ if (p) {
+ sig_ss7_set_alarm(p, 1);
+ }
}
break;
case MTP2_LINK_UP:
@@ -13471,9 +13384,9 @@
{
struct ast_frame f = { AST_FRAME_CONTROL, { AST_CONTROL_PROGRESS } };
ast_debug(1, "Queuing frame PROGRESS on CIC %d\n", p->cic);
- dahdi_queue_frame(p, &f, linkset);
+ sig_ss7_queue_frame(p, &f, linkset);
p->progress = 1;
- p->dialing = 0;
+ sig_ss7_set_dialing(p, 0);
if (p->dsp && p->dsp_features) {
ast_dsp_set_features(p->dsp, p->dsp_features);
p->dsp_features = 0;
@@ -13559,6 +13472,13 @@
} else
p->cid_num[0] = 0;
+ /* Set DNID */
+ if (!ast_strlen_zero(e->iam.called_party_num)) {
+ ss7_apply_plan_to_number(p->exten, sizeof(p->exten), linkset,
+ e->iam.called_party_num, e->iam.called_nai);
+ sig_ss7_set_dnid(p, p->exten);
+ }
+
if (p->immediate) {
p->exten[0] = 's';
p->exten[1] = '\0';
@@ -13566,10 +13486,12 @@
char *st;
ss7_apply_plan_to_number(p->exten, sizeof(p->exten), linkset, e->iam.called_party_num, e->iam.called_nai);
st = strchr(p->exten, '#');
- if (st)
+ if (st) {
*st = '\0';
- } else
- p->exten[0] = '\0';
+ }
+ } else {
+ p->exten[0] = '\0';
+ }
p->cid_ani[0] = '\0';
if ((p->use_callerid) && (!ast_strlen_zero(e->iam.generic_name)))
@@ -13593,10 +13515,6 @@
ast_copy_string(p->redirecting_num, e->iam.redirecting_num, sizeof(p->redirecting_num));
ast_copy_string(p->generic_name, e->iam.generic_name, sizeof(p->generic_name));
p->calling_party_cat = e->iam.calling_party_cat;
-
- /* Set DNID */
- if (!ast_strlen_zero(e->iam.called_party_num))
- ss7_apply_plan_to_number(p->dnid, sizeof(p->dnid), linkset, e->iam.called_party_num, e->iam.called_nai);
if (ast_exists_extension(NULL, p->context, p->exten, 1, p->cid_num)) {
@@ -13673,8 +13591,9 @@
if (p->owner) {
p->owner->hangupcause = e->rel.cause;
p->owner->_softhangup |= AST_SOFTHANGUP_DEV;
- } else if (!p->restartpending)
+ } else {
ast_log(LOG_WARNING, "REL on channel (CIC %d) without owner!\n", p->cic);
+ }
/* End the loopback if we have one */
sig_ss7_loopback(p, 0);
@@ -13702,9 +13621,9 @@
}
sig_ss7_lock_private(p);
- dahdi_queue_frame(p, &f, linkset);
+ sig_ss7_queue_frame(p, &f, linkset);
p->proceeding = 1;
- p->dialing = 0;
+ sig_ss7_set_dialing(p, 0);
/* Send alerting if subscriber is free */
if (e->acm.called_party_status_ind == 1) {
p->alerting = 1;
@@ -13816,7 +13735,7 @@
ast_dsp_set_features(p->dsp, p->dsp_features);
p->dsp_features = 0;
}
- dahdi_enable_ec(p);
+ sig_ss7_set_echocanceller(p, 1);
sig_ss7_unlock_private(p);
}
break;
@@ -15828,7 +15747,7 @@
}
for (i = 0; i < strlen(number); i++) {
struct ast_frame f = { AST_FRAME_DTMF, .subclass.integer = number[i] };
- dahdi_queue_frame(p, &f, NULL);
+ dahdi_queue_frame(p, &f);
}
astman_send_ack(s, m, "DAHDIDialOffhook");
return 0;
@@ -18189,6 +18108,229 @@
return 0;
}
/* BUGBUG sig_ss7 API functions ----v*/
+
+/*!
+ * \brief Determine if the specified channel is available for an outgoing call.
+ * \since 1.8
+ *
+ * \param p Signaling private structure pointer.
+ *
+ * \retval TRUE if the channel is available.
+ */
+int sig_ss7_available(struct sig_ss7_chan *p)
+{
+ if (!p->ss7) {
+ /* Something is wrong here. A SS7 channel without the ss7 pointer? */
+ return 0;
+ }
+
+ if (!p->inalarm && !p->owner && !p->ss7call
+ && !p->locallyblocked && !p->remotelyblocked) {
+ return 1;
+ }
+
+ return 0;
+}
+
+/*!
+ * \brief Dial out using the specified SS7 channel.
+ * \since 1.8
+ *
+ * \param p Signaling private structure pointer.
+ * \param ast Asterisk channel sructure pointer.
+ * \param rdest Dialstring.
+ *
+ * \retval 0 on success.
+ * \retval -1 on error.
+ */
+int sig_ss7_call(struct sig_ss7_chan *p, struct ast_channel *ast, char *rdest)
+{
+ char ss7_called_nai;
+ int called_nai_strip;
+ char ss7_calling_nai;
+ int calling_nai_strip;
+ const char *charge_str = NULL;
+ const char *gen_address = NULL;
+ const char *gen_digits = NULL;
+ const char *gen_dig_type = NULL;
+ const char *gen_dig_scheme = NULL;
+ const char *gen_name = NULL;
+ const char *jip_digits = NULL;
+ const char *lspi_ident = NULL;
+ const char *rlt_flag = NULL;
+ const char *call_ref_id = NULL;
+ const char *call_ref_pc = NULL;
+ const char *send_far = NULL;
+ char *c;
+ char *l;
+ char dest[256];
+
+ ast_copy_string(dest, rdest, sizeof(dest));
+
+ c = strchr(dest, '/');
+ if (c) {
+ c++;
+ } else {
+ c = "";
+ }
+ if (strlen(c) < p->stripmsd) {
+ ast_log(LOG_WARNING, "Number '%s' is shorter than stripmsd (%d)\n", c, p->stripmsd);
+ return -1;
+ }
+
+ if (!p->hidecallerid) {
+ l = ast->connected.id.number;
+ } else {
+ l = NULL;
+ }
+
+ if (ss7_grab(p, p->ss7)) {
+ ast_log(LOG_WARNING, "Failed to grab SS7!\n");
+ return -1;
+ }
+
+ p->ss7call = isup_new_call(p->ss7->ss7);
+ if (!p->ss7call) {
+ ss7_rel(p->ss7);
+ ast_log(LOG_ERROR, "Unable to allocate new SS7 call!\n");
+ return -1;
+ }
+
+ 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;
+ }
+ }
+ 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->connected.id.number_presentation) : (l ? SS7_PRESENTATION_ALLOWED : SS7_PRESENTATION_RESTRICTED),
+ p->use_callingpres ? cid_pres2ss7screen(ast->connected.id.number_presentation) : SS7_SCREENING_USER_PROVIDED );
+
+ isup_set_oli(p->ss7call, ast->connected.ani2);
+ isup_init_call(p->ss7->ss7, p->ss7call, p->cic, p->dpc);
+
+ /* Set the charge number if it is set */
+ charge_str = pbx_builtin_getvar_helper(ast, "SS7_CHARGE_NUMBER");
+ if (charge_str)
+ isup_set_charge(p->ss7call, charge_str, SS7_ANI_CALLING_PARTY_SUB_NUMBER, 0x10);
+
+ gen_address = pbx_builtin_getvar_helper(ast, "SS7_GENERIC_ADDRESS");
+ if (gen_address)
+ isup_set_gen_address(p->ss7call, gen_address, p->gen_add_nai,p->gen_add_pres_ind, p->gen_add_num_plan,p->gen_add_type); /* need to add some types here for NAI,PRES,TYPE */
+
+ gen_digits = pbx_builtin_getvar_helper(ast, "SS7_GENERIC_DIGITS");
+ gen_dig_type = pbx_builtin_getvar_helper(ast, "SS7_GENERIC_DIGTYPE");
+ gen_dig_scheme = pbx_builtin_getvar_helper(ast, "SS7_GENERIC_DIGSCHEME");
+ if (gen_digits)
+ isup_set_gen_digits(p->ss7call, gen_digits, atoi(gen_dig_type), atoi(gen_dig_scheme));
+
+ gen_name = pbx_builtin_getvar_helper(ast, "SS7_GENERIC_NAME");
+ if (gen_name)
+ isup_set_generic_name(p->ss7call, gen_name, GEN_NAME_TYPE_CALLING_NAME, GEN_NAME_AVAIL_AVAILABLE, GEN_NAME_PRES_ALLOWED);
+
+ jip_digits = pbx_builtin_getvar_helper(ast, "SS7_JIP");
+ if (jip_digits)
+ isup_set_jip_digits(p->ss7call, jip_digits);
+
+ lspi_ident = pbx_builtin_getvar_helper(ast, "SS7_LSPI_IDENT");
+ if (lspi_ident)
+ isup_set_lspi(p->ss7call, lspi_ident, 0x18, 0x7, 0x00);
+
+ rlt_flag = pbx_builtin_getvar_helper(ast, "SS7_RLT_ON");
+ if ((rlt_flag) && ((strncmp("NO", rlt_flag, strlen(rlt_flag))) != 0 )) {
+ isup_set_lspi(p->ss7call, rlt_flag, 0x18, 0x7, 0x00); /* Setting for Nortel DMS-250/500 */
+ }
+
+ call_ref_id = pbx_builtin_getvar_helper(ast, "SS7_CALLREF_IDENT");
+ call_ref_pc = pbx_builtin_getvar_helper(ast, "SS7_CALLREF_PC");
+ if (call_ref_id && call_ref_pc) {
+ isup_set_callref(p->ss7call, atoi(call_ref_id),
+ call_ref_pc ? atoi(call_ref_pc) : 0);
+ }
+
+ 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));
+
+ isup_iam(p->ss7->ss7, p->ss7call);
+ sig_ss7_set_dialing(p, 1);
+ ast_setstate(ast, AST_STATE_DIALING);
+ ss7_rel(p->ss7);
+}
+
+
+/*!
+ * \brief SS7 hangup channel.
+ * \since 1.8
+ *
+ * \param p Signaling private structure pointer.
+ * \param ast Asterisk channel sructure pointer.
+ *
+ * \retval 0 on success.
+ * \retval -1 on error.
+ */
+int sig_ss7_hangup(struct sig_ss7_chan *p, struct ast_channel *ast)
+{
+ int res = 0;
+
+ if (!ast->tech_pvt) {
+ ast_log(LOG_WARNING, "Asked to hangup channel not connected\n");
+ return 0;
+ }
+
+ sig_ss7_set_dialing(p, 0);
+ p->proceeding = 0;
+ p->progress = 0;
+ p->alerting = 0;
+ p->rlt = 0;
+ p->exten[0] = '\0';
+ /* Perform low level hangup if no owner left */
+ if (p->ss7call) {
+ if (!ss7_grab(p, p->ss7)) {
+ if (!p->alreadyhungup) {
+ const char *cause = pbx_builtin_getvar_helper(ast,"SS7_CAUSE");
+ int icause = ast->hangupcause ? ast->hangupcause : -1;
+
+ if (cause) {
+ if (atoi(cause))
+ icause = atoi(cause);
+ }
+ 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");
+ } else {
+ ast_log(LOG_WARNING, "Unable to grab SS7 on CIC %d\n", p->cic);
+ res = -1;
+ }
+ }
+
+ return res;
+}
+
/* BUGBUG sig_ss7 API functions ----^*/
Modified: team/rmudgett/sig_ss7/channels/sig_ss7.h
URL: http://svnview.digium.com/svn/asterisk/team/rmudgett/sig_ss7/channels/sig_ss7.h?view=diff&rev=261099&r1=261098&r2=261099
==============================================================================
--- team/rmudgett/sig_ss7/channels/sig_ss7.h (original)
+++ team/rmudgett/sig_ss7/channels/sig_ss7.h Tue May 4 19:14:31 2010
@@ -97,7 +97,8 @@
struct ast_channel * (* const new_ast_channel)(void *pvt, int state, int startpbx, enum sig_ss7_law law, char *exten, const struct ast_channel *requestor);
int (* const play_tone)(void *pvt, enum sig_ss7_tone tone);
- void (* const set_dialing)(void *pvt, int flag);
+ void (* const set_alarm)(void *pvt, int in_alarm);
+ void (* const set_dialing)(void *pvt, int is_dialing);
void (* const set_callerid)(void *pvt, const struct ast_party_caller *caller);
void (* const set_dnid)(void *pvt, const char *dnid);
void (* const set_rdnis)(void *pvt, const char *rdnis);
@@ -112,6 +113,37 @@
/*! \brief Opaque libss7 call control structure */
struct isup_call *ss7call;
+ /* Options to be set by user */
+ /*!
+ * \brief Number of most significant digits/characters to strip from the dialed number.
+ * \note Feature is deprecated. Use dialplan logic.
+ */
+ int stripmsd;
+ /*!
+ * \brief TRUE if the outgoing caller ID is blocked/hidden.
+ */
+ unsigned int hidecallerid:1;
+ /*! \brief TRUE if caller ID is used on this channel. */
+ unsigned int use_callerid:1;
+ /*!
+ * \brief TRUE if we will use the calling presentation setting
+ * from the Asterisk channel for outgoing calls.
+ */
+ unsigned int use_callingpres:1;
+ unsigned int immediate:1; /*!< Answer before getting digits? */
+
+ /* Options to be checked by user */
+ int cid_ani2; /*!< Automatic Number Identification number (Alternate PRI caller ID number) */
+ int cid_ton; /*!< Type Of Number (TON) */
+ int callingpres; /*!< The value of calling presentation that we're going to use when placing a PRI call */
+ char cid_num[AST_MAX_EXTENSION];
+ char cid_subaddr[AST_MAX_EXTENSION];/*!< BUGBUG SS7 may not support. */
+ char cid_name[AST_MAX_EXTENSION];
+ char cid_ani[AST_MAX_EXTENSION];
+ char exten[AST_MAX_EXTENSION];
+
+ /* Options to be set by user */
+ char context[AST_MAX_CONTEXT];
char charge_number[50];
char gen_add_number[50];
char gen_dig_number[50];
@@ -132,7 +164,6 @@
unsigned int call_ref_ident;
unsigned int call_ref_pc;
unsigned char calling_party_cat;
- int transcap;
int cic; /*!< CIC associated with channel */
unsigned int dpc; /*!< CIC's DPC */
int channel; /*!< Channel Number */
@@ -151,6 +182,19 @@
unsigned int inalarm:1;
unsigned int outgoing:1;
+ /*!
+ * \brief TRUE if call is in a proceeding state.
+ * The call has started working its way through the network.
+ */
+ unsigned int proceeding:1;
+ /*! \brief TRUE if the call has seen progress through the network. */
+ unsigned int progress:1;
+ /*! \brief TRUE if channel is alerting/ringing */
+ unsigned int alerting:1;
+ /*! \brief TRUE if the call has already gone/hungup */
+ unsigned int alreadyhungup:1;
+ /*! \brief XXX BOOLEAN Purpose??? */
+ unsigned int rlt:1;
};
struct sig_ss7_linkset {
@@ -178,6 +222,11 @@
struct sig_ss7_callback *calls;
};
+void sig_ss7_set_alarm(struct sig_ss7_chan *p, int in_alarm);
+int sig_ss7_available(struct sig_ss7_chan *p);
+int sig_ss7_call(struct sig_ss7_chan *p, struct ast_channel *ast, char *rdest);
+int sig_ss7_hangup(struct sig_ss7_chan *p, struct ast_channel *ast);
+
/* ------------------------------------------------------------------- */
More information about the asterisk-commits
mailing list