[asterisk-commits] dvossel: branch group/v6-new r267444 - in /team/group/v6-new: ./ channels/ ch...
SVN commits to the Asterisk project
asterisk-commits at lists.digium.com
Thu Jun 3 09:44:33 CDT 2010
Author: dvossel
Date: Thu Jun 3 09:44:29 2010
New Revision: 267444
URL: http://svnview.digium.com/svn/asterisk?view=rev&rev=267444
Log:
svnmerge merge
Modified:
team/group/v6-new/ (props changed)
team/group/v6-new/CHANGES
team/group/v6-new/channels/Makefile
team/group/v6-new/channels/chan_dahdi.c
team/group/v6-new/channels/h323/Makefile.in
team/group/v6-new/channels/sig_pri.c
team/group/v6-new/channels/sig_pri.h
team/group/v6-new/configs/chan_dahdi.conf.sample
team/group/v6-new/configure
team/group/v6-new/configure.ac
team/group/v6-new/include/asterisk/autoconfig.h.in
team/group/v6-new/include/asterisk/channel.h
team/group/v6-new/main/Makefile
team/group/v6-new/main/channel.c
team/group/v6-new/utils/extconf.c
Propchange: team/group/v6-new/
------------------------------------------------------------------------------
--- svnmerge-integrated (original)
+++ svnmerge-integrated Thu Jun 3 09:44:29 2010
@@ -1,1 +1,1 @@
-/trunk:1-267139
+/trunk:1-267443
Modified: team/group/v6-new/CHANGES
URL: http://svnview.digium.com/svn/asterisk/team/group/v6-new/CHANGES?view=diff&rev=267444&r1=267443&r2=267444
==============================================================================
--- team/group/v6-new/CHANGES (original)
+++ team/group/v6-new/CHANGES Thu Jun 3 09:44:29 2010
@@ -61,6 +61,8 @@
the particular peer. The dialstring format is SIP/peer/exten/host_or_IP.
* Added directmediapermit/directmediadeny to limit which peers can send direct media
to each other
+ * Added the 'snom_aoc_enabled' option to turn on support for sending Advice of
+ Charge messages to snom phones.
IAX2 Changes
-----------
@@ -203,6 +205,11 @@
prefixing the name of the hash at assignment with the appropriate number of
underscores, just like variables.
* GROUP_MATCH_COUNT has been improved to allow regex matching on category
+ * For DAHDI/ISDN channels, the CHANNEL() dialplan function now supports the
+ "no_media_path" option.
+ Returns "0" if there is a B channel associated with the call.
+ Returns "1" if no B channel is associated with the call. The call is either
+ on hold or is a call waiting call.
Dialplan Variables
------------------
@@ -336,6 +343,11 @@
to eliminate tromboned calls. A tromboned call goes out an interface and comes
back into the same interface. Tromboned calls happen because of call routing,
call deflection, call forwarding, and call transfer.
+ * Added the ability to send and receive ETSI Advice-Of-Charge messages.
+ * Added the ability to support call waiting calls. (The SETUP has no B channel
+ assigned.)
+ * Added Malicious Call ID (MCID) event to the AMI call event class.
+ * Added Message Waiting Indication (MWI) support for ISDN PTMP endpoints (phones).
Asterisk Manager Interface
--------------------------
@@ -366,6 +378,8 @@
'sip show peers'.
* Added Advice-Of-Charge events (AOC-S, AOC-D, and AOC-E) in the new
aoc event class.
+ * Added Advice-Of-Charge manager action, AOCMessage, for generating AOC-D and
+ AOC-E messages on a channel.
Channel Event Logging
---------------------
Modified: team/group/v6-new/channels/Makefile
URL: http://svnview.digium.com/svn/asterisk/team/group/v6-new/channels/Makefile?view=diff&rev=267444&r1=267443&r2=267444
==============================================================================
--- team/group/v6-new/channels/Makefile (original)
+++ team/group/v6-new/channels/Makefile Thu Jun 3 09:44:29 2010
@@ -63,8 +63,8 @@
clean::
$(MAKE) -C misdn clean
- if [ -f h323/Makefile ]; then $(MAKE) -C h323 clean; fi
rm -f sip/*.o sip/*.i
+ rm -f h323/libchanh323.a h323/Makefile.ast h323/*.o h323/*.dep
dist-clean::
rm -f h323/Makefile
Modified: team/group/v6-new/channels/chan_dahdi.c
URL: http://svnview.digium.com/svn/asterisk/team/group/v6-new/channels/chan_dahdi.c?view=diff&rev=267444&r1=267443&r2=267444
==============================================================================
--- team/group/v6-new/channels/chan_dahdi.c (original)
+++ team/group/v6-new/channels/chan_dahdi.c Thu Jun 3 09:44:29 2010
@@ -800,7 +800,10 @@
unsigned int didtdd:1; /*!< flag to say its done it once */
/*! \brief TRUE if analog type line dialed no digits in Dial() */
unsigned int dialednone:1;
- /*! \brief TRUE if in the process of dialing digits or sending something. */
+ /*!
+ * \brief TRUE if in the process of dialing digits or sending something.
+ * \note This is used as a receive squelch for ISDN until connected.
+ */
unsigned int dialing:1;
/*! \brief TRUE if the transfer capability of the call is digital. */
unsigned int digital:1;
@@ -1075,6 +1078,8 @@
* \note The "group" bitmapped group string read in from chan_dahdi.conf
*/
ast_group_t group;
+ /*! \brief Default call PCM encoding format: DAHDI_LAW_ALAW or DAHDI_LAW_MULAW. */
+ int law_default;
/*! \brief Active PCM encoding format: DAHDI_LAW_ALAW or DAHDI_LAW_MULAW */
int law;
int confno; /*!< Our conference */
@@ -2232,7 +2237,8 @@
p->dsp = NULL;
}
- law = DAHDI_LAW_DEFAULT;
+ p->law = p->law_default;
+ law = p->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));
@@ -2391,10 +2397,22 @@
int audio;
int newlaw = -1;
- /* Set to audio mode at this point */
- audio = 1;
- if (ioctl(p->subs[SUB_REAL].dfd, DAHDI_AUDIOMODE, &audio) == -1)
- ast_log(LOG_WARNING, "Unable to set audio mode on channel %d to %d: %s\n", p->channel, audio, strerror(errno));
+ switch (p->sig) {
+ case SIG_PRI_LIB_HANDLE_CASES:
+ if (((struct sig_pri_chan *) p->sig_pvt)->no_b_channel) {
+ /* PRI nobch pseudo channel. Does not handle ioctl(DAHDI_AUDIOMODE) */
+ break;
+ }
+ /* Fall through */
+ default:
+ /* Set to audio mode at this point */
+ audio = 1;
+ if (ioctl(p->subs[SUB_REAL].dfd, DAHDI_AUDIOMODE, &audio) == -1) {
+ ast_log(LOG_WARNING, "Unable to set audio mode on channel %d to %d: %s\n",
+ p->channel, audio, strerror(errno));
+ }
+ break;
+ }
if (law != SIG_PRI_DEFLAW) {
dahdi_setlaw(p->subs[SUB_REAL].dfd, (law == SIG_PRI_ULAW) ? DAHDI_LAW_MULAW : DAHDI_LAW_ALAW);
@@ -2414,6 +2432,54 @@
break;
}
return dahdi_new(p, state, startpbx, SUB_REAL, newlaw, transfercapability, requestor ? requestor->linkedid : "");
+}
+#endif /* defined(HAVE_PRI) */
+
+static int set_actual_gain(int fd, float rxgain, float txgain, float rxdrc, float txdrc, int law);
+
+#if defined(HAVE_PRI)
+/*!
+ * \internal
+ * \brief Open the PRI channel media path.
+ * \since 1.8
+ *
+ * \param p Channel private control structure.
+ *
+ * \return Nothing
+ */
+static void my_pri_open_media(void *p)
+{
+ struct dahdi_pvt *pvt = p;
+ int res;
+ int dfd;
+ int set_val;
+
+ dfd = pvt->subs[SUB_REAL].dfd;
+
+ /* Open the media path. */
+ set_val = 1;
+ res = ioctl(dfd, DAHDI_AUDIOMODE, &set_val);
+ if (res < 0) {
+ ast_log(LOG_WARNING, "Unable to enable audio mode on channel %d (%s)\n",
+ pvt->channel, strerror(errno));
+ }
+
+ /* Set correct companding law for this call. */
+ res = dahdi_setlaw(dfd, pvt->law);
+ if (res < 0) {
+ ast_log(LOG_WARNING, "Unable to set law on channel %d\n", pvt->channel);
+ }
+
+ /* Set correct gain for this call. */
+ if (pvt->digital) {
+ res = set_actual_gain(dfd, 0, 0, pvt->rxdrc, pvt->txdrc, pvt->law);
+ } else {
+ res = set_actual_gain(dfd, pvt->rxgain, pvt->txgain, pvt->rxdrc, pvt->txdrc,
+ pvt->law);
+ }
+ if (res < 0) {
+ ast_log(LOG_WARNING, "Unable to set gains on channel %d\n", pvt->channel);
+ }
}
#endif /* defined(HAVE_PRI) */
@@ -2734,6 +2800,17 @@
new_chan->dsp_features = old_chan->dsp_features;
old_chan->dsp = NULL;
old_chan->dsp_features = 0;
+
+ /* Transfer flags from the old channel. */
+ new_chan->dialing = old_chan->dialing;
+ new_chan->digital = old_chan->digital;
+ new_chan->outgoing = old_chan->outgoing;
+ old_chan->dialing = 0;
+ old_chan->digital = 0;
+ old_chan->outgoing = 0;
+
+ /* More stuff to transfer to the new channel. */
+ new_chan->law = old_chan->law;
}
static int sig_pri_tone_to_dahditone(enum sig_pri_tone tone)
@@ -2997,6 +3074,9 @@
ast_module_unref(ast_module_info->self);
}
+#if defined(HAVE_PRI_CALL_WAITING)
+static void my_pri_init_config(void *priv, struct sig_pri_pri *pri);
+#endif /* defined(HAVE_PRI_CALL_WAITING) */
static int dahdi_new_pri_nobch_channel(struct sig_pri_pri *pri);
static struct sig_pri_callback dahdi_pri_callbacks =
@@ -3016,11 +3096,15 @@
.set_dnid = my_pri_set_dnid,
.set_rdnis = my_pri_set_rdnis,
.new_nobch_intf = dahdi_new_pri_nobch_channel,
+#if defined(HAVE_PRI_CALL_WAITING)
+ .init_config = my_pri_init_config,
+#endif /* defined(HAVE_PRI_CALL_WAITING) */
.get_orig_dialstring = my_get_orig_dialstring,
.make_cc_dialstring = my_pri_make_cc_dialstring,
.update_span_devstate = dahdi_pri_update_span_devstate,
.module_ref = my_module_ref,
.module_unref = my_module_unref,
+ .open_media = my_pri_open_media,
};
#endif /* defined(HAVE_PRI) */
@@ -3155,6 +3239,7 @@
.set_needringing = my_set_needringing,
};
+/*! Round robin search locations. */
static struct dahdi_pvt *round_robin[32];
#if defined(HAVE_SS7)
@@ -4179,7 +4264,7 @@
if (slavechannel < 1) {
p->confno = zi.confno;
}
- memcpy(&c->curconf, &zi, sizeof(c->curconf));
+ c->curconf = zi;
ast_debug(1, "Added %d to conference %d/%d\n", c->dfd, c->curconf.confmode, c->curconf.confno);
return 0;
}
@@ -4850,13 +4935,8 @@
#ifdef HAVE_PRI
if (dahdi_sig_pri_lib_handles(p->sig)) {
- struct dahdi_params ps;
-
- memset(&ps, 0, sizeof(ps));
- if (ioctl(p->subs[SUB_REAL].dfd, DAHDI_GET_PARAMS, &ps)) {
- ast_log(LOG_ERROR, "Could not get params\n");
- }
- res = sig_pri_call(p->sig_pvt, ast, rdest, timeout, (ps.curlaw == DAHDI_LAW_MULAW) ? PRI_LAYER_1_ULAW : PRI_LAYER_1_ALAW);
+ res = sig_pri_call(p->sig_pvt, ast, rdest, timeout,
+ (p->law == DAHDI_LAW_ALAW) ? PRI_LAYER_1_ALAW : PRI_LAYER_1_ULAW);
ast_mutex_unlock(&p->lock);
return res;
}
@@ -5736,7 +5816,8 @@
}
revert_fax_buffers(p, ast);
dahdi_setlinear(p->subs[SUB_REAL].dfd, 0);
- law = DAHDI_LAW_DEFAULT;
+ p->law = p->law_default;
+ law = p->law_default;
res = ioctl(p->subs[SUB_REAL].dfd, DAHDI_SETLAW, &law);
dahdi_disable_ec(p);
update_conf(p);
@@ -5907,7 +5988,8 @@
revert_fax_buffers(p, ast);
- law = DAHDI_LAW_DEFAULT;
+ p->law = p->law_default;
+ law = p->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));
@@ -6464,6 +6546,22 @@
}
ast_mutex_unlock(&p->lock);
#endif /* defined(HAVE_PRI_SETUP_KEYPAD) */
+ } else if (!strcasecmp(data, "no_media_path")) {
+ ast_mutex_lock(&p->lock);
+ switch (p->sig) {
+ case SIG_PRI_LIB_HANDLE_CASES:
+ /*
+ * TRUE if the call is on hold or is call waiting because
+ * there is no media path available.
+ */
+ snprintf(buf, len, "%d", ((struct sig_pri_chan *) p->sig_pvt)->no_b_channel);
+ break;
+ default:
+ *buf = '\0';
+ res = -1;
+ break;
+ }
+ ast_mutex_unlock(&p->lock);
#endif /* defined(HAVE_PRI) */
} else {
*buf = '\0';
@@ -8871,12 +8969,10 @@
{
struct ast_channel *tmp;
format_t deflaw;
- int res;
int x;
int features;
struct ast_str *chan_name;
struct ast_variable *v;
- struct dahdi_params ps;
if (i->subs[idx].owner) {
ast_log(LOG_WARNING, "Channel %d already has a %s call\n", i->channel,subnames[idx]);
@@ -8907,21 +9003,29 @@
}
#endif /* defined(HAVE_PRI) */
ast_channel_cc_params_init(tmp, i->cc_params);
- memset(&ps, 0, sizeof(ps));
- res = ioctl(i->subs[SUB_REAL].dfd, DAHDI_GET_PARAMS, &ps);
- if (res) {
- ast_log(LOG_WARNING, "Unable to get parameters, assuming MULAW: %s\n", strerror(errno));
- ps.curlaw = DAHDI_LAW_MULAW;
- }
- if (ps.curlaw == DAHDI_LAW_ALAW)
- deflaw = AST_FORMAT_ALAW;
- else
- deflaw = AST_FORMAT_ULAW;
if (law) {
- if (law == DAHDI_LAW_ALAW)
+ i->law = law;
+ if (law == DAHDI_LAW_ALAW) {
deflaw = AST_FORMAT_ALAW;
- else
+ } else {
deflaw = AST_FORMAT_ULAW;
+ }
+ } else {
+ switch (i->sig) {
+ case SIG_PRI_LIB_HANDLE_CASES:
+ /* Make sure companding law is known. */
+ i->law = (i->law_default == DAHDI_LAW_ALAW)
+ ? DAHDI_LAW_ALAW : DAHDI_LAW_MULAW;
+ break;
+ default:
+ i->law = i->law_default;
+ break;
+ }
+ if (i->law_default == DAHDI_LAW_ALAW) {
+ deflaw = AST_FORMAT_ALAW;
+ } else {
+ deflaw = AST_FORMAT_ULAW;
+ }
}
ast_channel_set_fd(tmp, 0, i->subs[idx].dfd);
tmp->nativeformats = deflaw;
@@ -11538,6 +11642,7 @@
destroy_dahdi_pvt(tmp);
return NULL;
}
+ tmp->law_default = p.curlaw;
tmp->law = p.curlaw;
tmp->span = p.spanno;
span = p.spanno - 1;
@@ -11777,6 +11882,12 @@
pris[span].pri.cc_qsig_signaling_link_rsp =
conf->pri.pri.cc_qsig_signaling_link_rsp;
#endif /* defined(HAVE_PRI_CCSS) */
+#if defined(HAVE_PRI_CALL_WAITING)
+ pris[span].pri.max_call_waiting_calls =
+ conf->pri.pri.max_call_waiting_calls;
+ pris[span].pri.allow_call_waiting_calls =
+ conf->pri.pri.allow_call_waiting_calls;
+#endif /* defined(HAVE_PRI_CALL_WAITING) */
pris[span].pri.transfer = conf->chan.transfer;
pris[span].pri.facilityenable = conf->pri.pri.facilityenable;
#if defined(HAVE_PRI_AOC_EVENTS)
@@ -11784,6 +11895,11 @@
pris[span].pri.aoce_delayhangup = conf->pri.pri.aoce_delayhangup;
#endif /* defined(HAVE_PRI_AOC_EVENTS) */
ast_copy_string(pris[span].pri.msn_list, conf->pri.pri.msn_list, sizeof(pris[span].pri.msn_list));
+#if defined(HAVE_PRI_MWI)
+ ast_copy_string(pris[span].pri.mwi_mailboxes,
+ conf->pri.pri.mwi_mailboxes,
+ sizeof(pris[span].pri.mwi_mailboxes));
+#endif /* defined(HAVE_PRI_MWI) */
ast_copy_string(pris[span].pri.idledial, conf->pri.pri.idledial, sizeof(pris[span].pri.idledial));
ast_copy_string(pris[span].pri.idleext, conf->pri.pri.idleext, sizeof(pris[span].pri.idleext));
ast_copy_string(pris[span].pri.internationalprefix, conf->pri.pri.internationalprefix, sizeof(pris[span].pri.internationalprefix));
@@ -11796,6 +11912,20 @@
for (x = 0; x < PRI_MAX_TIMERS; x++) {
pris[span].pri.pritimers[x] = conf->pri.pri.pritimers[x];
}
+
+#if defined(HAVE_PRI_CALL_WAITING)
+ /* Channel initial config parameters. */
+ pris[span].pri.ch_cfg.stripmsd = conf->chan.stripmsd;
+ pris[span].pri.ch_cfg.hidecallerid = conf->chan.hidecallerid;
+ pris[span].pri.ch_cfg.hidecalleridname = conf->chan.hidecalleridname;
+ pris[span].pri.ch_cfg.immediate = conf->chan.immediate;
+ pris[span].pri.ch_cfg.priexclusive = conf->chan.priexclusive;
+ pris[span].pri.ch_cfg.priindication_oob = conf->chan.priindication_oob;
+ pris[span].pri.ch_cfg.use_callerid = conf->chan.use_callerid;
+ pris[span].pri.ch_cfg.use_callingpres = conf->chan.use_callingpres;
+ ast_copy_string(pris[span].pri.ch_cfg.context, conf->chan.context, sizeof(pris[span].pri.ch_cfg.context));
+ ast_copy_string(pris[span].pri.ch_cfg.mohinterpret, conf->chan.mohinterpret, sizeof(pris[span].pri.ch_cfg.mohinterpret));
+#endif /* defined(HAVE_PRI_CALL_WAITING) */
} else {
ast_log(LOG_ERROR, "Channel %d is reserved for D-channel.\n", p.chanpos);
destroy_dahdi_pvt(tmp);
@@ -12266,8 +12396,10 @@
return 1;
}
-static int available(struct dahdi_pvt *p)
-{
+static int available(struct dahdi_pvt **pvt, int is_specific_channel)
+{
+ struct dahdi_pvt *p = *pvt;
+
if (p->inalarm)
return 0;
@@ -12277,7 +12409,15 @@
#ifdef HAVE_PRI
switch (p->sig) {
case SIG_PRI_LIB_HANDLE_CASES:
- return sig_pri_available(p->sig_pvt);
+ {
+ struct sig_pri_chan *pvt_chan;
+ int res;
+
+ pvt_chan = p->sig_pvt;
+ res = sig_pri_available(&pvt_chan, is_specific_channel);
+ *pvt = pvt_chan->chan_pvt;
+ return res;
+ }
default:
break;
}
@@ -12314,6 +12454,38 @@
return 0;
}
+
+#if defined(HAVE_PRI)
+#if defined(HAVE_PRI_CALL_WAITING)
+/*!
+ * \internal
+ * \brief Init the private channel configuration using the span controller.
+ * \since 1.8
+ *
+ * \param priv Channel to init the configuration.
+ * \param pri sig_pri PRI control structure.
+ *
+ * \note Assumes the pri->lock is already obtained.
+ *
+ * \return Nothing
+ */
+static void my_pri_init_config(void *priv, struct sig_pri_pri *pri)
+{
+ struct dahdi_pvt *pvt = priv;
+
+ pvt->stripmsd = pri->ch_cfg.stripmsd;
+ pvt->hidecallerid = pri->ch_cfg.hidecallerid;
+ pvt->hidecalleridname = pri->ch_cfg.hidecalleridname;
+ pvt->immediate = pri->ch_cfg.immediate;
+ pvt->priexclusive = pri->ch_cfg.priexclusive;
+ pvt->priindication_oob = pri->ch_cfg.priindication_oob;
+ pvt->use_callerid = pri->ch_cfg.use_callerid;
+ pvt->use_callingpres = pri->ch_cfg.use_callingpres;
+ ast_copy_string(pvt->context, pri->ch_cfg.context, sizeof(pvt->context));
+ ast_copy_string(pvt->mohinterpret, pri->ch_cfg.mohinterpret, sizeof(pvt->mohinterpret));
+}
+#endif /* defined(HAVE_PRI_CALL_WAITING) */
+#endif /* defined(HAVE_PRI) */
#if defined(HAVE_PRI)
/*!
@@ -12381,7 +12553,15 @@
}
chan->no_b_channel = 1;
+ /*
+ * Pseudo channel companding law.
+ * Needed for outgoing call waiting calls.
+ * XXX May need to make this determined by switchtype or user option.
+ */
+ pvt->law_default = DAHDI_LAW_ALAW;
+
pvt->sig = pri->sig;
+ pvt->outsigmod = -1;
pvt->pri = pri;
pvt->sig_pvt = chan;
pri->pvts[pvt_idx] = chan;
@@ -12577,13 +12757,18 @@
} else
p = iflist;
} else {
+ if (ARRAY_LEN(round_robin) <= x) {
+ ast_log(LOG_WARNING, "Round robin index %d out of range for data %s\n",
+ x, data);
+ return NULL;
+ }
if (args.group[0] == 'R') {
param->backwards = 1;
- p = round_robin[x]?round_robin[x]->prev:ifend;
+ p = round_robin[x] ? round_robin[x]->prev : ifend;
if (!p)
p = ifend;
} else {
- p = round_robin[x]?round_robin[x]->next:iflist;
+ p = round_robin[x] ? round_robin[x]->next : iflist;
if (!p)
p = iflist;
}
@@ -12643,7 +12828,7 @@
round_robin[start.rr_starting_point] = p;
if (is_group_or_channel_match(p, start.span, start.groupmatch, &groupmatched, start.channelmatch, &channelmatched)
- && available(p)) {
+ && available(&p, channelmatched)) {
ast_debug(1, "Using channel %d\n", p->channel);
callwait = (p->owner != NULL);
@@ -12702,6 +12887,20 @@
}
if (!tmp) {
p->outgoing = 0;
+#if defined(HAVE_PRI)
+#if defined(HAVE_PRI_CALL_WAITING)
+ switch (p->sig) {
+ case SIG_PRI_LIB_HANDLE_CASES:
+ if (((struct sig_pri_chan *) p->sig_pvt)->is_call_waiting) {
+ ((struct sig_pri_chan *) p->sig_pvt)->is_call_waiting = 0;
+ ast_atomic_fetchadd_int(&p->pri->num_call_waiting_calls, -1);
+ }
+ break;
+ default:
+ break;
+ }
+#endif /* defined(HAVE_PRI_CALL_WAITING) */
+#endif /* defined(HAVE_PRI) */
} else {
snprintf(p->dialstring, sizeof(p->dialstring), "DAHDI/%s", (char *) data);
}
@@ -15090,7 +15289,7 @@
ast_cli(a->fd, "TDD: %s\n", tmp->tdd ? "yes" : "no");
ast_cli(a->fd, "Relax DTMF: %s\n", tmp->dtmfrelax ? "yes" : "no");
ast_cli(a->fd, "Dialing/CallwaitCAS: %d/%d\n", tmp->dialing, tmp->callwaitcas);
- ast_cli(a->fd, "Default law: %s\n", tmp->law == DAHDI_LAW_MULAW ? "ulaw" : tmp->law == DAHDI_LAW_ALAW ? "alaw" : "unknown");
+ ast_cli(a->fd, "Default law: %s\n", tmp->law_default == DAHDI_LAW_MULAW ? "ulaw" : tmp->law_default == DAHDI_LAW_ALAW ? "alaw" : "unknown");
ast_cli(a->fd, "Fax Handled: %s\n", tmp->faxhandled ? "yes" : "no");
ast_cli(a->fd, "Pulse phone: %s\n", tmp->pulsedial ? "yes" : "no");
ast_cli(a->fd, "Gains (RX/TX): %.2f/%.2f\n", tmp->rxgain, tmp->txgain);
@@ -16392,6 +16591,7 @@
for (j = 0; j < SIG_PRI_NUM_DCHANS; j++) {
dahdi_close_pri_fd(&(pris[i]), j);
}
+ sig_pri_stop_pri(&pris[i].pri);
}
#if defined(HAVE_PRI_CCSS)
ast_cc_agent_unregister(&dahdi_pri_cc_agent_callbacks);
@@ -17246,6 +17446,21 @@
confp->pri.pri.cc_qsig_signaling_link_rsp = 1;/* retain */
}
#endif /* defined(HAVE_PRI_CCSS) */
+#if defined(HAVE_PRI_CALL_WAITING)
+ } else if (!strcasecmp(v->name, "max_call_waiting_calls")) {
+ confp->pri.pri.max_call_waiting_calls = atoi(v->value);
+ if (confp->pri.pri.max_call_waiting_calls < 0) {
+ /* Negative values are not allowed. */
+ confp->pri.pri.max_call_waiting_calls = 0;
+ }
+ } else if (!strcasecmp(v->name, "allow_call_waiting_calls")) {
+ confp->pri.pri.allow_call_waiting_calls = ast_true(v->value);
+#endif /* defined(HAVE_PRI_CALL_WAITING) */
+#if defined(HAVE_PRI_MWI)
+ } else if (!strcasecmp(v->name, "mwi_mailboxes")) {
+ ast_copy_string(confp->pri.pri.mwi_mailboxes, v->value,
+ sizeof(confp->pri.pri.mwi_mailboxes));
+#endif /* defined(HAVE_PRI_MWI) */
#endif /* HAVE_PRI */
#ifdef HAVE_SS7
} else if (!strcasecmp(v->name, "ss7type")) {
Modified: team/group/v6-new/channels/h323/Makefile.in
URL: http://svnview.digium.com/svn/asterisk/team/group/v6-new/channels/h323/Makefile.in?view=diff&rev=267444&r1=267443&r2=267444
==============================================================================
--- team/group/v6-new/channels/h323/Makefile.in (original)
+++ team/group/v6-new/channels/h323/Makefile.in Thu Jun 3 09:44:29 2010
@@ -47,4 +47,3 @@
@if [ -r $@ ] && cmp -s $@ $@.tmp; then rm -f $@.tmp; else mv -f $@.tmp $@; fi
clean::
- rm -f $(TARGET) $(OBJS) Makefile.ast *.dep
Modified: team/group/v6-new/channels/sig_pri.c
URL: http://svnview.digium.com/svn/asterisk/team/group/v6-new/channels/sig_pri.c?view=diff&rev=267444&r1=267443&r2=267444
==============================================================================
--- team/group/v6-new/channels/sig_pri.c (original)
+++ team/group/v6-new/channels/sig_pri.c Thu Jun 3 09:44:29 2010
@@ -814,6 +814,26 @@
return c;
}
+/*!
+ * \internal
+ * \brief Open the PRI channel media path.
+ * \since 1.8
+ *
+ * \param p Channel private control structure.
+ *
+ * \return Nothing
+ */
+static void sig_pri_open_media(struct sig_pri_chan *p)
+{
+ if (p->no_b_channel) {
+ return;
+ }
+
+ if (p->calls->open_media) {
+ p->calls->open_media(p->chan_pvt);
+ }
+}
+
struct ast_channel *sig_pri_request(struct sig_pri_chan *p, enum sig_pri_law law, const struct ast_channel *requestor, int transfercapability)
{
struct ast_channel *ast;
@@ -982,15 +1002,17 @@
int x;
int span;
int principle;
+ int prioffset;
if (channel < 0) {
/* Channel is not picked yet. */
return -1;
}
- if (channel & PRI_HELD_CALL) {
+ prioffset = PRI_CHANNEL(channel);
+ if (!prioffset || (channel & PRI_HELD_CALL)) {
if (!call) {
- /* Cannot find a held call without a call. */
+ /* Cannot find a call waiting call or held call without a call. */
return -1;
}
principle = -1;
@@ -1015,11 +1037,10 @@
span = pri->dchan_logical_span[index];
}
- channel = PRI_CHANNEL(channel);
principle = -1;
for (x = 0; x < pri->numchans; x++) {
if (pri->pvts[x]
- && pri->pvts[x]->prioffset == channel
+ && pri->pvts[x]->prioffset == prioffset
&& pri->pvts[x]->logicalspan == span
&& !pri->pvts[x]->no_b_channel) {
principle = x;
@@ -1079,6 +1100,11 @@
old_chan->call = NULL;
/* Transfer flags from the old channel. */
+#if defined(HAVE_PRI_AOC_EVENTS)
+ new_chan->aoc_s_request_invoke_id_valid = old_chan->aoc_s_request_invoke_id_valid;
+ new_chan->waiting_for_aoce = old_chan->waiting_for_aoce;
+ new_chan->holding_aoce = old_chan->holding_aoce;
+#endif /* defined(HAVE_PRI_AOC_EVENTS) */
new_chan->alerting = old_chan->alerting;
new_chan->alreadyhungup = old_chan->alreadyhungup;
new_chan->isidlecall = old_chan->isidlecall;
@@ -1087,17 +1113,14 @@
new_chan->setup_ack = old_chan->setup_ack;
new_chan->outgoing = old_chan->outgoing;
new_chan->digital = old_chan->digital;
+#if defined(HAVE_PRI_CALL_WAITING)
+ new_chan->is_call_waiting = old_chan->is_call_waiting;
+#endif /* defined(HAVE_PRI_CALL_WAITING) */
+
#if defined(HAVE_PRI_AOC_EVENTS)
- new_chan->aoc_s_request_invoke_id = old_chan->aoc_s_request_invoke_id;
- new_chan->aoc_s_request_invoke_id_valid = old_chan->aoc_s_request_invoke_id_valid;
- new_chan->holding_aoce = old_chan->holding_aoce;
- new_chan->waiting_for_aoce = old_chan->waiting_for_aoce;
- new_chan->aoc_e = old_chan->aoc_e;
-
- old_chan->holding_aoce = 0;
old_chan->aoc_s_request_invoke_id_valid = 0;
old_chan->waiting_for_aoce = 0;
- memset(&old_chan->aoc_e, 0, sizeof(&old_chan->aoc_e));
+ old_chan->holding_aoce = 0;
#endif /* defined(HAVE_PRI_AOC_EVENTS) */
old_chan->alerting = 0;
old_chan->alreadyhungup = 0;
@@ -1107,6 +1130,9 @@
old_chan->setup_ack = 0;
old_chan->outgoing = 0;
old_chan->digital = 0;
+#if defined(HAVE_PRI_CALL_WAITING)
+ old_chan->is_call_waiting = 0;
+#endif /* defined(HAVE_PRI_CALL_WAITING) */
/* More stuff to transfer to the new channel. */
#if defined(HAVE_PRI_REVERSE_CHARGE)
@@ -1115,6 +1141,10 @@
#if defined(HAVE_PRI_SETUP_KEYPAD)
strcpy(new_chan->keypad_digits, old_chan->keypad_digits);
#endif /* defined(HAVE_PRI_SETUP_KEYPAD) */
+#if defined(HAVE_PRI_AOC_EVENTS)
+ new_chan->aoc_s_request_invoke_id = old_chan->aoc_s_request_invoke_id;
+ new_chan->aoc_e = old_chan->aoc_e;
+#endif /* defined(HAVE_PRI_AOC_EVENTS) */
if (new_chan->no_b_channel) {
/* Copy the real channel configuration to the no B channel interface. */
@@ -1222,6 +1252,38 @@
}
return 0;
}
+
+#if defined(HAVE_PRI_CALL_WAITING)
+/*!
+ * \internal
+ * \brief Init the private channel configuration using the span controller.
+ * \since 1.8
+ *
+ * \param pvt Channel to init the configuration.
+ * \param pri sig_pri PRI control structure.
+ *
+ * \note Assumes the pri->lock is already obtained.
+ *
+ * \return Nothing
+ */
+static void sig_pri_init_config(struct sig_pri_chan *pvt, struct sig_pri_pri *pri)
+{
+ pvt->stripmsd = pri->ch_cfg.stripmsd;
+ pvt->hidecallerid = pri->ch_cfg.hidecallerid;
+ pvt->hidecalleridname = pri->ch_cfg.hidecalleridname;
+ pvt->immediate = pri->ch_cfg.immediate;
+ pvt->priexclusive = pri->ch_cfg.priexclusive;
+ pvt->priindication_oob = pri->ch_cfg.priindication_oob;
+ pvt->use_callerid = pri->ch_cfg.use_callerid;
+ pvt->use_callingpres = pri->ch_cfg.use_callingpres;
+ ast_copy_string(pvt->context, pri->ch_cfg.context, sizeof(pvt->context));
+ ast_copy_string(pvt->mohinterpret, pri->ch_cfg.mohinterpret, sizeof(pvt->mohinterpret));
+
+ if (pri->calls->init_config) {
+ pri->calls->init_config(pvt->chan_pvt, pri);
+ }
+}
+#endif /* defined(HAVE_PRI_CALL_WAITING) */
static int pri_find_empty_chan(struct sig_pri_pri *pri, int backwards)
{
@@ -1581,6 +1643,98 @@
/* Did not match any pattern in the list. */
return 0;
}
+
+#if defined(HAVE_PRI_MCID)
+/*!
+ * \internal
+ * \brief Append the given party id to the event string.
+ * \since 1.8
+ *
+ * \param msg Event message string being built.
+ * \param prefix Prefix to add to the party id lines.
+ * \param party Party information to encode.
+ *
+ * \return Nothing
+ */
+static void sig_pri_event_party_id(struct ast_str **msg, const char *prefix, struct ast_party_id *party)
+{
+ ast_str_append(msg, 0, "%sPres: %d (%s)\r\n", prefix,
+ party->number_presentation,
+ ast_describe_caller_presentation(party->number_presentation));
+ ast_str_append(msg, 0, "%sNum: %s\r\n", prefix, S_OR(party->number, ""));
+ ast_str_append(msg, 0, "%ston: %d\r\n", prefix, party->number_type);
+ ast_str_append(msg, 0, "%sName: %s\r\n", prefix, S_OR(party->name, ""));
+#if defined(HAVE_PRI_SUBADDR)
+ if (party->subaddress.valid) {
+ static const char subaddress[] = "Subaddr";
+
+ ast_str_append(msg, 0, "%s%s: %s\r\n", prefix, subaddress,
+ S_OR(party->subaddress.str, ""));
+ ast_str_append(msg, 0, "%s%sType: %d\r\n", prefix, subaddress,
+ party->subaddress.type);
+ ast_str_append(msg, 0, "%s%sOdd: %d\r\n", prefix, subaddress,
+ party->subaddress.odd_even_indicator);
+ }
+#endif /* defined(HAVE_PRI_SUBADDR) */
+}
+#endif /* defined(HAVE_PRI_MCID) */
+
+#if defined(HAVE_PRI_MCID)
+/*!
+ * \internal
+ * \brief Handle the MCID event.
+ * \since 1.8
+ *
+ * \param pri sig_pri PRI control structure.
+ * \param mcid MCID event parameters.
+ * \param owner Asterisk channel associated with the call.
+ * NULL if Asterisk no longer has the ast_channel struct.
+ *
+ * \note Assumes the pri->lock is already obtained.
+ * \note Assumes the owner channel lock is already obtained if still present.
+ *
+ * \return Nothing
+ */
+static void sig_pri_mcid_event(struct sig_pri_pri *pri, const struct pri_subcmd_mcid_req *mcid, struct ast_channel *owner)
+{
+ struct ast_channel *chans[1];
+ struct ast_str *msg;
+ struct ast_party_id party;
+
+ msg = ast_str_create(4096);
+ if (!msg) {
+ return;
+ }
+
+ if (owner) {
+ /* The owner channel is present. */
+ ast_str_append(&msg, 0, "Channel: %s\r\n", owner->name);
+ ast_str_append(&msg, 0, "UniqueID: %s\r\n", owner->uniqueid);
+
+ sig_pri_event_party_id(&msg, "CallerID", &owner->connected.id);
+ } else {
+ /*
+ * Since we no longer have an owner channel,
+ * we have to use the caller information supplied by libpri.
+ */
+ ast_party_id_init(&party);
+ sig_pri_party_id_convert(&party, &mcid->originator, pri);
+ sig_pri_event_party_id(&msg, "CallerID", &party);
+ ast_party_id_free(&party);
+ }
+
+ /* Always use libpri's called party information. */
+ ast_party_id_init(&party);
+ sig_pri_party_id_convert(&party, &mcid->answerer, pri);
+ sig_pri_event_party_id(&msg, "ConnectedID", &party);
+ ast_party_id_free(&party);
+
+ chans[0] = owner;
+ ast_manager_event_multichan(EVENT_FLAG_CALL, "MCID", owner ? 1 : 0, chans, "%s",
+ ast_str_buffer(msg));
+ ast_free(msg);
+}
+#endif /* defined(HAVE_PRI_MCID) */
#if defined(HAVE_PRI_CALL_HOLD) || defined(HAVE_PRI_TRANSFER)
/*!
@@ -3519,7 +3673,8 @@
sig_pri_lock_owner(pri, chanpos);
owner = pri->pvts[chanpos]->owner;
if (owner) {
- sig_pri_aoc_s_from_pri(&subcmd->u.aoc_s, owner, (pri->aoc_passthrough_flag & SIG_PRI_AOC_GRANT_S));
+ sig_pri_aoc_s_from_pri(&subcmd->u.aoc_s, owner,
+ (pri->aoc_passthrough_flag & SIG_PRI_AOC_GRANT_S));
ast_channel_unlock(owner);
}
break;
@@ -3530,7 +3685,8 @@
owner = pri->pvts[chanpos]->owner;
if (owner) {
/* Queue AST_CONTROL_AOC frame on channel */
- sig_pri_aoc_d_from_pri(&subcmd->u.aoc_d, owner, (pri->aoc_passthrough_flag & SIG_PRI_AOC_GRANT_D));
+ sig_pri_aoc_d_from_pri(&subcmd->u.aoc_d, owner,
+ (pri->aoc_passthrough_flag & SIG_PRI_AOC_GRANT_D));
ast_channel_unlock(owner);
}
break;
@@ -3540,7 +3696,8 @@
sig_pri_lock_owner(pri, chanpos);
owner = pri->pvts[chanpos]->owner;
/* Queue AST_CONTROL_AOC frame */
- sig_pri_aoc_e_from_pri(&subcmd->u.aoc_e, owner, (pri->aoc_passthrough_flag & SIG_PRI_AOC_GRANT_E));
+ sig_pri_aoc_e_from_pri(&subcmd->u.aoc_e, owner,
+ (pri->aoc_passthrough_flag & SIG_PRI_AOC_GRANT_E));
if (owner) {
ast_channel_unlock(owner);
}
@@ -3551,25 +3708,45 @@
sig_pri_lock_owner(pri, chanpos);
owner = pri->pvts[chanpos]->owner;
if (owner) {
- sig_pri_aoc_request_from_pri(&subcmd->u.aoc_request, pri->pvts[chanpos], call_rsp);
+ sig_pri_aoc_request_from_pri(&subcmd->u.aoc_request, pri->pvts[chanpos],
+ call_rsp);
ast_channel_unlock(owner);
}
break;
#endif /* defined(HAVE_PRI_AOC_EVENTS) */
#if defined(HAVE_PRI_AOC_EVENTS)
case PRI_SUBCMD_AOC_CHARGING_REQ_RSP:
- /* An AOC request response may contain an AOC-S rate list. If this is the case handle this just like we
- * would an incoming AOC-S msg */
+ /*
+ * An AOC request response may contain an AOC-S rate list.
+ * If this is the case handle this just like we
+ * would an incoming AOC-S msg.
+ */
if (subcmd->u.aoc_request_response.valid_aoc_s) {
sig_pri_lock_owner(pri, chanpos);
owner = pri->pvts[chanpos]->owner;
if (owner) {
- sig_pri_aoc_s_from_pri(&subcmd->u.aoc_request_response.aoc_s, owner, (pri->aoc_passthrough_flag & SIG_PRI_AOC_GRANT_S));
+ sig_pri_aoc_s_from_pri(&subcmd->u.aoc_request_response.aoc_s, owner,
+ (pri->aoc_passthrough_flag & SIG_PRI_AOC_GRANT_S));
ast_channel_unlock(owner);
}
}
break;
#endif /* defined(HAVE_PRI_AOC_EVENTS) */
+#if defined(HAVE_PRI_MCID)
+ case PRI_SUBCMD_MCID_REQ:
+ sig_pri_lock_owner(pri, chanpos);
+ owner = pri->pvts[chanpos]->owner;
+ sig_pri_mcid_event(pri, &subcmd->u.mcid_req, owner);
+ if (owner) {
+ ast_channel_unlock(owner);
+ }
+ break;
+#endif /* defined(HAVE_PRI_MCID) */
+#if defined(HAVE_PRI_MCID)
+ case PRI_SUBCMD_MCID_RSP:
+ /* Ignore for now. */
+ break;
+#endif /* defined(HAVE_PRI_MCID) */
default:
ast_debug(2,
"Unknown call subcommand(%d) in %s event on channel %d/%d on span %d.\n",
@@ -4175,10 +4352,33 @@
e->ring.call);
break;
}
- if (e->ring.channel == -1 || PRI_CHANNEL(e->ring.channel) == 0xFF)
+ if (e->ring.channel == -1 || PRI_CHANNEL(e->ring.channel) == 0xFF) {
+ /* Any channel requested. */
chanpos = pri_find_empty_chan(pri, 1);
- else
+ } else if (PRI_CHANNEL(e->ring.channel) == 0x00) {
+ /* No channel specified. */
+#if defined(HAVE_PRI_CALL_WAITING)
+ if (!pri->allow_call_waiting_calls)
+#endif /* defined(HAVE_PRI_CALL_WAITING) */
+ {
+ /* We will not accept incoming call waiting calls. */
+ pri_hangup(pri->pri, e->ring.call, PRI_CAUSE_INCOMPATIBLE_DESTINATION);
+ break;
+ }
+#if defined(HAVE_PRI_CALL_WAITING)
+ chanpos = pri_find_empty_nobch(pri);
+ if (chanpos < 0) {
+ /* We could not find/create a call interface. */
+ pri_hangup(pri->pri, e->ring.call, PRI_CAUSE_NORMAL_CIRCUIT_CONGESTION);
+ break;
+ }
+ /* Setup the call interface to use. */
+ sig_pri_init_config(pri->pvts[chanpos], pri);
+#endif /* defined(HAVE_PRI_CALL_WAITING) */
+ } else {
+ /* A channel is specified. */
chanpos = pri_find_principle(pri, e->ring.channel, e->ring.call);
+ }
/* if no channel specified find one empty */
if (chanpos < 0) {
ast_log(LOG_WARNING, "Ring requested on unconfigured channel %d/%d span %d\n",
@@ -4571,43 +4771,33 @@
sig_pri_lock_private(pri->pvts[chanpos]);
sig_pri_handle_subcmds(pri, chanpos, e->e, e->proceeding.channel,
e->proceeding.subcmds, e->proceeding.call);
- if ((!pri->pvts[chanpos]->progress)
+
+ if (e->proceeding.cause > -1) {
+ ast_verb(3, "PROGRESS with cause code %d received\n", e->proceeding.cause);
+
+ /* Work around broken, out of spec USER_BUSY cause in a progress message */
+ if (e->proceeding.cause == AST_CAUSE_USER_BUSY) {
+ if (pri->pvts[chanpos]->owner) {
+ ast_verb(3, "PROGRESS with 'user busy' received, signaling AST_CONTROL_BUSY instead of AST_CONTROL_PROGRESS\n");
+
+ pri->pvts[chanpos]->owner->hangupcause = e->proceeding.cause;
+ pri_queue_control(pri, chanpos, AST_CONTROL_BUSY);
+ }
+ }
+ }
+
+ if (!pri->pvts[chanpos]->progress
+ && !pri->pvts[chanpos]->no_b_channel
#ifdef PRI_PROGRESS_MASK
- || (e->proceeding.progressmask & PRI_PROG_INBAND_AVAILABLE)
+ && (e->proceeding.progressmask & PRI_PROG_INBAND_AVAILABLE)
#else
- || (e->proceeding.progress == 8)
+ && e->proceeding.progress == 8
#endif
) {
- int subclass;
-
- subclass = AST_CONTROL_PROGRESS;
- if (e->proceeding.cause > -1) {
- ast_verb(3, "PROGRESS with cause code %d received\n", e->proceeding.cause);
-
- /* Work around broken, out of spec USER_BUSY cause in a progress message */
- if (e->proceeding.cause == AST_CAUSE_USER_BUSY) {
- if (pri->pvts[chanpos]->owner) {
- ast_verb(3, "PROGRESS with 'user busy' received, signaling AST_CONTROL_BUSY instead of AST_CONTROL_PROGRESS\n");
-
- pri->pvts[chanpos]->owner->hangupcause = e->proceeding.cause;
- subclass = AST_CONTROL_BUSY;
- }
- }
- }
-
+ /* Bring voice path up */
ast_debug(1, "Queuing frame from PRI_EVENT_PROGRESS on channel %d/%d span %d\n",
pri->pvts[chanpos]->logicalspan, pri->pvts[chanpos]->prioffset,pri->span);
- pri_queue_control(pri, chanpos, subclass);
- if (
-#ifdef PRI_PROGRESS_MASK
- e->proceeding.progressmask & PRI_PROG_INBAND_AVAILABLE
-#else
- e->proceeding.progress == 8
-#endif
- ) {
- /* Bring voice path up */
- pri_queue_control(pri, chanpos, AST_CONTROL_PROGRESS);
- }
+ pri_queue_control(pri, chanpos, AST_CONTROL_PROGRESS);
pri->pvts[chanpos]->progress = 1;
sig_pri_set_dialing(pri->pvts[chanpos], 0);
}
@@ -4629,17 +4819,19 @@
ast_debug(1, "Queuing frame from PRI_EVENT_PROCEEDING on channel %d/%d span %d\n",
pri->pvts[chanpos]->logicalspan, pri->pvts[chanpos]->prioffset,pri->span);
pri_queue_control(pri, chanpos, AST_CONTROL_PROCEEDING);
- if (
+ pri->pvts[chanpos]->proceeding = 1;
+ }
+ if (!pri->pvts[chanpos]->progress
+ && !pri->pvts[chanpos]->no_b_channel
#ifdef PRI_PROGRESS_MASK
- e->proceeding.progressmask & PRI_PROG_INBAND_AVAILABLE
+ && (e->proceeding.progressmask & PRI_PROG_INBAND_AVAILABLE)
#else
- e->proceeding.progress == 8
+ && e->proceeding.progress == 8
#endif
- ) {
- /* Bring voice path up */
- pri_queue_control(pri, chanpos, AST_CONTROL_PROGRESS);
- }
- pri->pvts[chanpos]->proceeding = 1;
+ ) {
+ /* Bring voice path up */
+ pri_queue_control(pri, chanpos, AST_CONTROL_PROGRESS);
+ pri->pvts[chanpos]->progress = 1;
sig_pri_set_dialing(pri->pvts[chanpos], 0);
}
sig_pri_unlock_private(pri->pvts[chanpos]);
@@ -4689,39 +4881,127 @@
if (chanpos < 0) {
ast_log(LOG_WARNING, "Answer on unconfigured channel %d/%d span %d\n",
PRI_SPAN(e->answer.channel), PRI_CHANNEL(e->answer.channel), pri->span);
+ break;
+ }
+ chanpos = pri_fixup_principle(pri, chanpos, e->answer.call);
+ if (chanpos < 0) {
+ ast_log(LOG_WARNING, "Answer requested on channel %d/%d not in use on span %d\n",
+ PRI_SPAN(e->answer.channel), PRI_CHANNEL(e->answer.channel), pri->span);
+ break;
+ }
+#if defined(HAVE_PRI_CALL_WAITING)
+ if (pri->pvts[chanpos]->is_call_waiting) {
+ if (pri->pvts[chanpos]->no_b_channel) {
+ int new_chanpos;
+
+ /*
+ * Need to find a free channel now or
+ * kill the call with PRI_CAUSE_NORMAL_CIRCUIT_CONGESTION.
+ */
+ new_chanpos = pri_find_empty_chan(pri, 1);
+ if (new_chanpos < 0) {
+ sig_pri_lock_private(pri->pvts[chanpos]);
+ sig_pri_handle_subcmds(pri, chanpos, e->e, e->answer.channel,
+ e->answer.subcmds, e->answer.call);
+ sig_pri_cc_generic_check(pri, chanpos, AST_CC_CCBS);
+ if (pri->pvts[chanpos]->owner) {
+ pri->pvts[chanpos]->owner->hangupcause = PRI_CAUSE_NORMAL_CIRCUIT_CONGESTION;
+ switch (pri->pvts[chanpos]->owner->_state) {
+ case AST_STATE_BUSY:
+ case AST_STATE_UP:
+ ast_softhangup_nolock(pri->pvts[chanpos]->owner, AST_SOFTHANGUP_DEV);
+ break;
+ default:
+ pri_queue_control(pri, chanpos, AST_CONTROL_CONGESTION);
+ break;
+ }
+ } else {
+ pri->pvts[chanpos]->is_call_waiting = 0;
+ ast_atomic_fetchadd_int(&pri->num_call_waiting_calls, -1);
+ pri_hangup(pri->pri, e->answer.call, PRI_CAUSE_NORMAL_CIRCUIT_CONGESTION);
+ pri->pvts[chanpos]->call = NULL;
+ }
+ sig_pri_unlock_private(pri->pvts[chanpos]);
+ break;
+ }
+ chanpos = pri_fixup_principle(pri, new_chanpos, e->answer.call);
+ if (chanpos < 0) {
[... 1077 lines stripped ...]
More information about the asterisk-commits
mailing list