[asterisk-commits] moy: branch moy/dahdi-advanced-tap-1.6.2 r220547 - /team/moy/dahdi-advanced-t...
SVN commits to the Asterisk project
asterisk-commits at lists.digium.com
Fri Sep 25 15:17:17 CDT 2009
Author: moy
Date: Fri Sep 25 15:17:12 2009
New Revision: 220547
URL: http://svnview.digium.com/svn/asterisk?view=rev&rev=220547
Log:
initial support for launching a passive ast channel into the dial plan
Modified:
team/moy/dahdi-advanced-tap-1.6.2/channels/chan_dahdi.c
Modified: team/moy/dahdi-advanced-tap-1.6.2/channels/chan_dahdi.c
URL: http://svnview.digium.com/svn/asterisk/team/moy/dahdi-advanced-tap-1.6.2/channels/chan_dahdi.c?view=diff&rev=220547&r1=220546&r2=220547
==============================================================================
--- team/moy/dahdi-advanced-tap-1.6.2/channels/chan_dahdi.c (original)
+++ team/moy/dahdi-advanced-tap-1.6.2/channels/chan_dahdi.c Fri Sep 25 15:17:12 2009
@@ -106,8 +106,6 @@
#include "asterisk/event.h"
#include "asterisk/devicestate.h"
#include "asterisk/paths.h"
-#include "asterisk/pbx.h"
-#include "asterisk/features.h"
/*** DOCUMENTATION
<application name="DAHDISendKeypadFacility" language="en_US">
@@ -570,6 +568,7 @@
#define MAX_FORMAT_EXTEN 10
#define DEFAULT_RECORDING_EXTEN "wav49"
char passiverecordexten[MAX_FORMAT_EXTEN]; /*!< Record format extension */
+ struct dahdi_pri *passivepeer; /*!< Peer PRI structure in passive mode */
struct dahdi_pvt *pvts[MAX_CHANNELS]; /*!< Member channel pvt structs */
struct dahdi_pvt *crvs; /*!< Member CRV structs */
struct dahdi_pvt *crvend; /*!< Pointer to end of CRV structs */
@@ -1190,6 +1189,10 @@
int prioffset;
/*! \brief Logical span number within trunk group */
int logicalspan;
+ /*!< Passive peer pvt we're related to, if any */
+ struct dahdi_pvt *passivepeer;
+ int passiveconf;
+ int passivefd;
#endif
/*! \brief Current line interface polarity. POLARITY_IDLE, POLARITY_REV */
int polarity;
@@ -4149,17 +4152,6 @@
#endif /* defined(HAVE_PRI) */
#if defined(HAVE_PRI)
-static struct dahdi_pri *pri_find_by_span(int span)
-{
- int x;
- for (x = 0; x < NUM_SPANS; x++) {
- if (pris[x].span == span) {
- return &pris[x];
- }
- }
- return NULL;
-}
-
static int pri_find_dchan(struct dahdi_pri *pri)
{
int oldslot = -1;
@@ -4359,6 +4351,17 @@
}
x = 0;
+ if (p->passivefd != -1) {
+ struct dahdi_confinfo pinfo;
+ memset(&pinfo, 0, sizeof(pinfo));
+ ioctl(p->subs[SUB_REAL].dfd, DAHDI_SETCONF);
+ memset(&pinfo, 0, sizeof(pinfo));
+ ioctl(p->passivepeer->subs[SUB_REAL].dfd, DAHDI_SETCONF);
+ memset(&pinfo, 0, sizeof(pinfo));
+ ioctl(p->passivefd, DAHDI_SETCONF);
+ dahdi_close(p->passivefd);
+ p->passivefd = -1;
+ }
dahdi_confmute(p, 0);
p->muting = 0;
restore_gains(p);
@@ -6909,30 +6912,43 @@
}
readbuf = ((unsigned char *)p->subs[idx].buffer) + AST_FRIENDLY_OFFSET;
CHECK_BLOCKING(ast);
- res = read(p->subs[idx].dfd, readbuf, p->subs[idx].linear ? READ_SIZE * 2 : READ_SIZE);
+#define CHECK_READ_RESULT(res) \
+ if (res < 0) { \
+ f = NULL; \
+ if (res == -1) { \
+ if (errno == EAGAIN) { \
+ ast_mutex_unlock(&p->lock); \
+ return &p->subs[idx].f; \
+ } else if (errno == ELAST) { \
+ f = __dahdi_exception(ast); \
+ } else { \
+ ast_log(LOG_WARNING, "dahdi_read: %s\n", strerror(errno)); \
+ } \
+ } \
+ ast_mutex_unlock(&p->lock); \
+ return f; \
+ } \
+ if (res != (p->subs[idx].linear ? READ_SIZE * 2 : READ_SIZE)) { \
+ ast_debug(1, "Short read (%d/%d), must be an event...\n", res, p->subs[idx].linear ? READ_SIZE * 2 : READ_SIZE); \
+ f = __dahdi_exception(ast); \
+ ast_mutex_unlock(&p->lock); \
+ return f; \
+ }
+
+ if (p->passivefd == -1) {
+ res = read(p->subs[idx].dfd, readbuf, p->subs[idx].linear ? READ_SIZE * 2 : READ_SIZE);
+ } else {
+ /* first read from the 2 involved dahdi channels */
+ res = read(p->subs[idx].dfd, readbuf, p->subs[idx].linear ? READ_SIZE * 2 : READ_SIZE);
+ CHECK_READ_RESULT(res);
+ res = read(p->passivepeer->subs[idx].dfd, readbuf, p->subs[idx].linear ? READ_SIZE * 2 : READ_SIZE);
+ CHECK_READ_RESULT(res);
+ /* now read the mixed audio that will be returned to the core */
+ res = read(p->passivefd, readbuf, p->subs[idx].linear ? READ_SIZE * 2 : READ_SIZE);
+ }
ast_clear_flag(ast, AST_FLAG_BLOCKING);
/* Check for hangup */
- if (res < 0) {
- f = NULL;
- if (res == -1) {
- if (errno == EAGAIN) {
- /* Return "NULL" frame if there is nobody there */
- ast_mutex_unlock(&p->lock);
- return &p->subs[idx].f;
- } else if (errno == ELAST) {
- f = __dahdi_exception(ast);
- } else
- ast_log(LOG_WARNING, "dahdi_rec: %s\n", strerror(errno));
- }
- ast_mutex_unlock(&p->lock);
- return f;
- }
- if (res != (p->subs[idx].linear ? READ_SIZE * 2 : READ_SIZE)) {
- ast_debug(1, "Short read (%d/%d), must be an event...\n", res, p->subs[idx].linear ? READ_SIZE * 2 : READ_SIZE);
- f = __dahdi_exception(ast);
- ast_mutex_unlock(&p->lock);
- return f;
- }
+ CHECK_READ_RESULT(res);
if (p->tdd) { /* if in TDD mode, see if we receive that */
int c;
@@ -7111,6 +7127,10 @@
if (idx < 0) {
ast_log(LOG_WARNING, "%s doesn't really exist?\n", ast->name);
return -1;
+ }
+
+ if (p->passivepeer) {
+ return 0;
}
#if 0
@@ -10293,6 +10313,8 @@
tmp->pri = &pris[span];
tmp->prioffset = offset;
tmp->call = NULL;
+ tmp->passiveconf = 0;
+ tmp->passivefd = -1;
} else {
ast_log(LOG_ERROR, "Channel %d is reserved for D-channel.\n", offset);
destroy_dahdi_pvt(&tmp);
@@ -12377,50 +12399,6 @@
#endif /* defined(HAVE_PRI) */
#if defined(HAVE_PRI)
-struct dahdi_pri_bridge_info
-{
- struct ast_channel *chan;
- struct ast_channel *peer;
-};
-
-static void *pri_bridge_call(void *args)
-{
- struct ast_bridge_config bconfig = { { 0, }, };
- int ret = 0;
- struct dahdi_pri_bridge_info *binfo = args;
- ast_log(LOG_NOTICE, "Bridging passive PRI channels %s and %s\n", binfo->chan->name, binfo->peer->name);
- ret = ast_bridge_call(binfo->chan, binfo->peer, &bconfig);
- ast_log(LOG_NOTICE, "Done bridging passive PRI channels %s and %s\n", binfo->chan->name, binfo->chan->name);
- ast_hangup(binfo->chan);
- ast_hangup(binfo->peer);
- ast_free(binfo);
- return NULL;
-}
-
-static void launch_pri_bridge_thread(struct ast_channel *c1, struct ast_channel *c2)
-{
- struct dahdi_pri_bridge_info *binfo = NULL;
- pthread_t thread;
- pthread_attr_t attr;
- pthread_attr_init(&attr);
- pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
-
- binfo = ast_calloc(1, sizeof(*binfo));
- if (!binfo) {
- ast_log(LOG_ERROR, "Failed to create PRI bridge info structure\n");
- return;
- }
-
- binfo->chan = c1;
- binfo->peer = c2;
- if (ast_pthread_create_background(&thread, &attr, pri_bridge_call, binfo)) {
- ast_log(LOG_ERROR, "Failed to create PRI bridge thread\n");
- return;
- }
-
- pthread_attr_destroy(&attr);
-}
-
/* Not thread-safe, we assume nobody else is looking for a passive call slot at the same time in this pri */
static struct dahdi_pcall *pri_get_pcall(struct dahdi_pri *pri, void *callref)
{
@@ -12436,8 +12414,10 @@
static struct dahdi_pcall *pri_get_crv_pcall(struct dahdi_pri *pri, int crv)
{
int i;
+ int tstcrv;
for (i = 0; i < ARRAY_LEN(pri->pcalls); i++) {
- if (pri->pcalls[i].callref && pri_get_crv(pri->pri, pri->pcalls[i].callref, NULL) == crv) {
+ tstcrv = pri->pcalls[i].callref ? pri_get_crv(pri->pri, pri->pcalls[i].callref, NULL) : 0;
+ if (pri->pcalls[i].callref && tstcrv == crv) {
return &pri->pcalls[i];
}
}
@@ -12456,25 +12436,21 @@
static void handle_pri_passive_event(struct dahdi_pri *pri, pri_event *e)
{
- int chanpos, peerpos, law, layer1, transcap, res;
+ int chanpos, peerpos, law, layer1, transcap, res, fd;
struct dahdi_pcall *pcall = NULL;
- struct ast_app *app = NULL;
struct ast_channel *c = NULL;
- struct ast_channel *peer = NULL;
- struct ast_tm tm;
- struct timeval now;
- char mixfilename[512];
- char datestr[50];
- int peerspan = !(pri->span % 2) ? (pri->span - 1) : (pri->span + 1);
- struct dahdi_pri *peerpri = pri_find_by_span(peerspan);
+ struct dahdi_pri *peerpri = pri->passivepeer;
+ struct dahdi_confinfo dahdic = { 0, };
+
if (!peerpri) {
ast_log(LOG_ERROR, "Ignoring passive PRI event on span %d, no peer span found!\n", pri->span);
return;
}
+
switch (e->e) {
case PRI_EVENT_RING:
- ast_log(LOG_DEBUG, "Ring on channel %d of span %d\n", e->ring.channel, pri->span);
+ ast_log(LOG_DEBUG, "Ring on channel %d of span %d with callref %d\n", e->ring.channel, pri->span, e->ring.cref);
/* we cannot use any pri->pvts data structure because we still dont know which channel will be used and therefore cant get
* chanpos (ie, flexible channel was requested), thus, we need our own list of call references */
pcall = pri_get_pcall(pri, NULL);
@@ -12497,21 +12473,6 @@
ast_log(LOG_DEBUG, "Proceed on channel %d of span %d\n", e->proceeding.channel, pri->span);
/* at this point we should know the real b chan that will be used and can therefore proceed to setup the ast channels, but
* only if a couple of call tests are passed */
-
- /* check that the layer 1 and trans capability are supported
- * we could have saved layer 1 and capability when receiving the PRI_EVENT_RING, but that requires maintaining
- * those values somewhere until the PROCEEDING msg arrives, no point in doing so, better we ask libpri at this
- * point the right values since libpri keeps those values anyways. Note that even though PRI_TRANS_CAP_SPEECH
- * and AST_TRANS_CAP_SPEECH conveniently have the same value, we don't assume it
- * the settings of the call are in the peer call structure because we are the originating side, and therefore
- * we did not get a PRI_EVENT_RING event
- * */
- peerpos = pri_find_principle(peerpri, e->proceeding.channel);
- if (peerpos < 0) {
- ast_log(LOG_ERROR, "Proceeding requested on odd/unavailable channel number %d/%d on peer span %d\n",
- PRI_SPAN(e->proceeding.channel), PRI_CHANNEL(e->proceeding.channel), peerpri->span);
- break;
- }
/* check that we already know about this call in the peer PRI (which was the one receiving the PRI_EVENT_RING event) */
if (!(pcall = pri_get_crv_pcall(peerpri, pri_get_crv(pri->pri, e->proceeding.call, NULL)))) {
@@ -12523,6 +12484,7 @@
pri->span, e->proceeding.cref, peerpri->span);
break;
}
+ /* check that the layer 1 and trans capability are supported */
layer1 = pri_get_layer1(peerpri->pri, pcall->callref);
transcap = pri_get_transcap(peerpri->pri, pcall->callref);
@@ -12535,15 +12497,26 @@
break;
}
+ /* check for valid channels in both the current span and the peer span */
chanpos = pri_find_principle(pri, e->proceeding.channel);
if (chanpos < 0) {
ast_log(LOG_ERROR, "Proceeding requested on odd/unavailable channel number %d/%d on span %d\n",
PRI_SPAN(e->proceeding.channel), PRI_CHANNEL(e->proceeding.channel), pri->span);
break;
}
+
+ peerpos = pri_find_principle(peerpri, e->proceeding.channel);
+ if (peerpos < 0) {
+ ast_log(LOG_ERROR, "Proceeding requested on odd/unavailable peer channel number %d/%d on span %d\n",
+ PRI_SPAN(e->proceeding.channel), PRI_CHANNEL(e->proceeding.channel), pri->span);
+ break;
+ }
+
+ /* save the call reference */
pri->pvts[chanpos]->call = e->proceeding.call;
-
- /* Set calling and called information */
+ peerpri->pvts[peerpos]->call = e->proceeding.call;
+
+ /* Set calling and callee information */
ast_copy_string(pri->pvts[chanpos]->cid_num, pcall->callingnum, sizeof(pri->pvts[chanpos]->cid_num));
ast_shrink_phone_number(pri->pvts[chanpos]->cid_num);
#ifdef PRI_ANI
@@ -12572,7 +12545,7 @@
ast_copy_string(pri->pvts[chanpos]->dnid, pcall->callednum, sizeof(pri->pvts[chanpos]->dnid));
}
- /* create the actual ast_channel but dont start a pbx, all will be handled by us */
+ /* create the actual ast_channel but dont start a pbx just yet */
law = layer1 == PRI_LAYER_1_ULAW ? DAHDI_LAW_MULAW : DAHDI_LAW_ALAW;
c = dahdi_new(pri->pvts[chanpos], AST_STATE_RINGING, 0, SUB_REAL, law, AST_TRANS_CAP_SPEECH);
if (!c) {
@@ -12580,31 +12553,96 @@
PRI_SPAN(e->restart.channel), PRI_CHANNEL(e->restart.channel), pri->span);
break;
}
+
res = dahdi_setlaw(pri->pvts[chanpos]->subs[SUB_REAL].dfd, law);
if (res < 0) {
- ast_log(LOG_WARNING, "Unable to set law on channel %d\n", pri->pvts[chanpos]->channel);
+ ast_log(LOG_WARNING, "Unable to set law on channel %d: %s\n", pri->pvts[chanpos]->channel, strerror(errno));
}
res = set_actual_gain(pri->pvts[chanpos]->subs[SUB_REAL].dfd, 0, pri->pvts[chanpos]->rxgain, pri->pvts[chanpos]->txgain, law);
if (res < 0) {
- ast_log(LOG_WARNING, "Unable to set gains on channel %d\n", pri->pvts[chanpos]->channel);
+ ast_log(LOG_WARNING, "Unable to set gains on channel %d: %s\n", pri->pvts[chanpos]->channel, strerror(errno));
}
res = ioctl(pri->pvts[chanpos]->subs[SUB_REAL].dfd, DAHDI_AUDIOMODE, &law);
if (res < 0) {
ast_log(LOG_WARNING, "Unable to set audio mode on channel %d to %d: %s\n", pri->pvts[chanpos]->channel, law, strerror(errno));
}
+
+ res = dahdi_setlaw(peerpri->pvts[chanpos]->subs[SUB_REAL].dfd, law);
+ if (res < 0) {
+ ast_log(LOG_WARNING, "Unable to set law on peer channel %d: %s\n", peerpri->pvts[chanpos]->channel, strerror(errno));
+ }
+ res = set_actual_gain(peerpri->pvts[chanpos]->subs[SUB_REAL].dfd, 0, peerpri->pvts[chanpos]->rxgain, peerpri->pvts[chanpos]->txgain, law);
+ if (res < 0) {
+ ast_log(LOG_WARNING, "Unable to set gains on peer channel %d: %s\n", peerpri->pvts[chanpos]->channel, strerror(errno));
+ }
+ res = ioctl(peerpri->pvts[chanpos]->subs[SUB_REAL].dfd, DAHDI_AUDIOMODE, &law);
+ if (res < 0) {
+ ast_log(LOG_WARNING, "Unable to set audio mode on peer channel %d to %d: %s\n", peerpri->pvts[chanpos]->channel, law, strerror(errno));
+ }
+
+ /* the owner for the peer channel will be the same, both dahdi pvt structures will share the owner,
+ * however Asterisk core will only know about one pvt structure, any future read will be done through
+ * the conference descriptor
+ * */
pri->pvts[chanpos]->owner = c;
- ast_log(LOG_DEBUG, "Set owner %s on span %d pos %d\n", c->name, pri->span, chanpos);
-
- /* now setup the bridged peer, far more easy, no need to set any fields */
- c = dahdi_new(peerpri->pvts[chanpos], AST_STATE_RINGING, 0, SUB_REAL, DAHDI_LAW_MULAW, AST_TRANS_CAP_SPEECH);
- if (!c) {
- ast_log(LOG_ERROR, "Failed to create channel for call on channel %d/%d on peer span %d\n",
- PRI_SPAN(e->restart.channel), PRI_CHANNEL(e->restart.channel), peerpri->span);
+ pri->pvts[chanpos]->passivepeer = peerpri->pvts[peerpos];
+ peerpri->pvts[peerpos]->owner = c;
+ peerpri->pvts[peerpos]->passivepeer = pri->pvts[chanpos];
+
+ /* create the mixing conference
+ * some DAHDI_SETCONF interface rules to keep in mind
+ * confno == -1 means create new conference with the given confmode
+ * confno and confmode == 0 means remove the channel from its conference */
+ dahdic.chan = 0; /* means use current channel (the one the fd belongs to)*/
+ dahdic.confno = -1; /* -1 means create new conference */
+ dahdic.confmode = DAHDI_CONF_CONFMON | DAHDI_CONF_LISTENER | DAHDI_CONF_PSEUDO_LISTENER;
+ fd = dahdi_open("/dev/dahdi/pseudo");
+ /* TODO: what about setting DAHDI_POLICY_IMMEDIATE and buf size? DAHDI_SETLINEAR?? */
+ if (fd < 0 || ioctl(fd, DAHDI_SETCONF, &dahdic)) {
+ ast_log(LOG_ERROR, "Unable to create dahdi conference for tapping\n");
+ break;
+ }
+ pri->pvts[chanpos]->passiveconf = dahdic.confno;
+ pri->pvts[chanpos]->passivefd = fd;
+
+ /* add both parties to the conference */
+ dahdic.chan = 0;
+ dahdic.confno = pri->pvts[chanpos]->passiveconf;
+ dahdic.confmode = DAHDI_CONF_CONF | DAHDI_CONF_TALKER;
+ if (ioctl(pri->pvts[chanpos]->subs[SUB_REAL].dfd, DAHDI_SETCONF, &dahdic)) {
+ ast_log(LOG_ERROR, "Unable to add chan to conference for tapping devices: %s\n", strerror(errno));
break;
}
- peerpri->pvts[peerpos]->owner = c;
- ast_log(LOG_DEBUG, "Set owner %s on peer span %d pos %d\n", c->name, peerpri->span, chanpos);
-
+ dahdic.chan = 0;
+ dahdic.confno = pri->pvts[chanpos]->passiveconf;
+ dahdic.confmode = DAHDI_CONF_CONF | DAHDI_CONF_TALKER;
+ if (ioctl(peerpri->pvts[chanpos]->subs[SUB_REAL].dfd, DAHDI_SETCONF, &dahdic)) {
+ ast_log(LOG_ERROR, "Unable to add peer chan to conference for tapping devices: %s\n", strerror(errno));
+ break;
+ }
+ ast_log(LOG_DEBUG, "Created conference %d with fd %d between dahdi chans %d and %d for ast channel %s\n",
+ pri->pvts[chanpos]->passiveconf,
+ pri->pvts[chanpos]->passivefd,
+ pri->pvts[chanpos]->channel,
+ peerpri->pvts[peerpos]->channel,
+ c->name);
+
+ /* from now on, reading from the conference has the mix of both tapped channels, we can now launch the pbx thread */
+ law = 1;
+ pri->pvts[chanpos]->subs[SUB_REAL].linear = 1;
+ peerpri->pvts[peerpos]->subs[SUB_REAL].linear = 1;
+ dahdi_setlinear(pri->pvts[chanpos]->subs[SUB_REAL].dfd, law);
+ dahdi_setlinear(pri->pvts[chanpos]->passivefd, law);
+ dahdi_setlinear(peerpri->pvts[peerpos]->subs[SUB_REAL].dfd, law);
+ c->rawreadformat = AST_FORMAT_SLINEAR;
+ c->nativeformats = AST_FORMAT_SLINEAR;
+ if (ast_set_read_format(c, AST_FORMAT_SLINEAR)) {
+ ast_log(LOG_WARNING, "Unable to set '%s' to read linear mode\n", c->name);
+ }
+ if (ast_pbx_start(c) != AST_PBX_SUCCESS) {
+ ast_log(LOG_ERROR, "Failed to launch PBX thread for passive channel %s\n", c->name);
+ ast_hangup(c);
+ }
break;
case PRI_EVENT_ANSWER:
@@ -12619,67 +12657,33 @@
}
if (!pri->pvts[chanpos]->owner) {
- ast_log(LOG_ERROR, "No owner on answer in channel number %d/%d on span %d\n",
+ /* this may be a valid condition if the user hangup the ast channel before the tapped line is answered */
+ ast_log(LOG_NOTICE, "Ignoring answer in tapped channel number %d/%d on span %d, no owner found\n",
PRI_SPAN(e->answer.channel), PRI_CHANNEL(e->answer.channel), pri->span);
break;
}
- /* save the owner and set its state as UP */
+ /* set the owner state as UP */
c = pri->pvts[chanpos]->owner;
ast_setstate(c, AST_STATE_UP);
-
- /* Now launch the monitor in the answered channel */
- app = pbx_findapp("MixMonitor");
- if (!app) {
- ast_log(LOG_ERROR, "Failed to find MixMonitor application to record audio for channel number %d/%d on span %d\n",
- PRI_SPAN(e->answer.channel), PRI_CHANNEL(e->answer.channel), pri->span);
- break;
- }
- now = ast_tvnow();
- ast_localtime(&now, &tm, NULL);
- ast_strftime(datestr, sizeof(datestr), "%F-%H-%M-%S", &tm);
- snprintf(mixfilename, sizeof(mixfilename), "dahdi-tap-%s-span-%d-chan-%d-mix.%s",
- datestr, pri->span, PRI_CHANNEL(e->answer.channel), pri->passiverecordexten);
- mixfilename[sizeof(mixfilename)-1] = '\0';
- if (pbx_exec(pri->pvts[chanpos]->owner, app, mixfilename)) {
- ast_log(LOG_ERROR, "Failed to launch MixMonitor application to record audio for channel number %d/%d on span %d\n",
- PRI_SPAN(e->answer.channel), PRI_CHANNEL(e->answer.channel), pri->span);
- break;
- }
-
- /* now get the peer channel and verify its owner */
- chanpos = pri_find_principle(peerpri, e->answer.channel);
- if (chanpos < 0) {
- ast_log(LOG_WARNING, "Answer requested on odd/unavailable channel number %d/%d on peer span %d\n",
- PRI_SPAN(e->answer.channel), PRI_CHANNEL(e->answer.channel), pri->span);
- break;
- }
-
- if (!peerpri->pvts[chanpos]->owner) {
- ast_log(LOG_WARNING, "No peer owner on answer in channel number %d/%d on peer span %d\n",
- PRI_SPAN(e->answer.channel), PRI_CHANNEL(e->answer.channel), peerpri->span);
- break;
- }
-
- /* save the peer and set its state as UP */
- peer = peerpri->pvts[chanpos]->owner;
- ast_setstate(peer, AST_STATE_UP);
-
- /* Now put both channels in a bridge in their own thread, MixMonitor is taking care of the rest */
- launch_pri_bridge_thread(c, peer);
break;
case PRI_EVENT_HANGUP:
- ast_log(LOG_NOTICE, "Hangup on channel %d of span %d\n", e->hangup.channel, pri->span);
+ ast_log(LOG_DEBUG, "Hangup on channel %d of span %d\n", e->hangup.channel, pri->span);
chanpos = pri_find_principle(pri, e->hangup.channel);
if (chanpos < 0) {
ast_log(LOG_ERROR, "Hangup requested on odd/unavailable channel number %d/%d on span %d\n",
PRI_SPAN(e->hangup.channel), PRI_CHANNEL(e->hangup.channel), pri->span);
break;
}
+ /* first put back the passive call slot, if any was used, since
+ * regardless of whethere there is owner or not, this resource must be freed */
+ pri_put_pcall(pri, e->hangup.call);
+
if (!pri->pvts[chanpos]->owner) {
- ast_log(LOG_ERROR, "No owner on hangup in channel number %d/%d on span %d\n",
+ /* this may be a valid condition if the user hangup the ast channel before the tapped line is terminated */
+ ast_log(LOG_NOTICE, "Ignoring hangup in tapped channel number %d/%d on span %d, no owner found\n",
PRI_SPAN(e->hangup.channel), PRI_CHANNEL(e->hangup.channel), pri->span);
break;
}
@@ -12693,14 +12697,13 @@
}
if (!peerpri->pvts[chanpos]->owner) {
- ast_log(LOG_ERROR, "No owner on hangup in channel number %d/%d on peer span %d\n",
+ /* invalid, since the owner is the same for both pvts, the owner should be here too */
+ ast_log(LOG_ERROR, "No owner on hangup in channel number %d/%d on peer span %d!!!??\n",
PRI_SPAN(e->hangup.channel), PRI_CHANNEL(e->hangup.channel), peerpri->span);
break;
}
ast_queue_hangup(peerpri->pvts[chanpos]->owner);
- /* put back the passive call slot, if any was used */
- pri_put_pcall(pri, e->hangup.call);
break;
case PRI_EVENT_HANGUP_ACK:
@@ -17664,6 +17667,10 @@
int x;
for (x = 0; x < NUM_SPANS; x++) {
if (pris[x].pvts[0]) {
+ if (pris[x].passive) {
+ int peerspan = !(x % 2) ? (x + 1) : (x - 1);
+ pris[x].passivepeer = &pris[peerspan];
+ }
if (start_pri(pris + x)) {
ast_log(LOG_ERROR, "Unable to start D-channel on span %d\n", x + 1);
return -1;
More information about the asterisk-commits
mailing list