[asterisk-commits] rmudgett: branch rmudgett/dahdi_facility r218691 - /team/rmudgett/dahdi_facil...
SVN commits to the Asterisk project
asterisk-commits at lists.digium.com
Tue Sep 15 14:51:32 CDT 2009
Author: rmudgett
Date: Tue Sep 15 14:51:27 2009
New Revision: 218691
URL: http://svn.asterisk.org/svn-view/asterisk?view=rev&rev=218691
Log:
Create dynamic no B channel interfaces for call hold support.
Work in progress.
Next need to handle the new HOLD/RETRIEVE events from libpri.
Modified:
team/rmudgett/dahdi_facility/channels/chan_dahdi.c
team/rmudgett/dahdi_facility/channels/sig_pri.c
team/rmudgett/dahdi_facility/channels/sig_pri.h
Modified: team/rmudgett/dahdi_facility/channels/chan_dahdi.c
URL: http://svn.asterisk.org/svn-view/asterisk/team/rmudgett/dahdi_facility/channels/chan_dahdi.c?view=diff&rev=218691&r1=218690&r2=218691
==============================================================================
--- team/rmudgett/dahdi_facility/channels/chan_dahdi.c (original)
+++ team/rmudgett/dahdi_facility/channels/chan_dahdi.c Tue Sep 15 14:51:27 2009
@@ -293,8 +293,6 @@
/*! \brief Typically, how many rings before we should send Caller*ID */
#define DEFAULT_CIDRINGS 1
-#define CHANNEL_PSEUDO -12
-
#define AST_LAW(p) (((p)->law == DAHDI_LAW_ALAW) ? AST_FORMAT_ALAW : AST_FORMAT_ULAW)
@@ -685,6 +683,9 @@
enum DAHDI_IFLIST {
DAHDI_IFLIST_NONE, /*!< The dahdi_pvt is not in any list. */
DAHDI_IFLIST_MAIN, /*!< The dahdi_pvt is in the main interface list */
+#if defined(HAVE_PRI)
+ DAHDI_IFLIST_NO_B_CHAN, /*!< The dahdi_pvt is in a no B channel interface list */
+#endif /* defined(HAVE_PRI) */
};
struct dahdi_pvt {
@@ -1258,6 +1259,15 @@
static struct dahdi_pvt *iflist = NULL; /*!< Main interface list start */
static struct dahdi_pvt *ifend = NULL; /*!< Main interface list end */
+#if defined(HAVE_PRI)
+static struct dahdi_parms_pseudo {
+ int buf_no; /*!< Number of buffers */
+ int buf_policy; /*!< Buffer policy */
+ int faxbuf_no; /*!< Number of Fax buffers */
+ int faxbuf_policy; /*!< Fax buffer policy */
+} dahdi_pseudo_parms;
+#endif /* defined(HAVE_PRI) */
+
/*! \brief Channel configuration from chan_dahdi.conf .
* This struct is used for parsing the [channels] section of chan_dahdi.conf.
* Generally there is a field here for every possible configuration item.
@@ -2598,7 +2608,8 @@
if (new_chan->owner) {
char newname[AST_CHANNEL_NAME];
- snprintf(newname, sizeof(newname), "DAHDI/%d:%d-%d", pri->trunkgroup, new_chan->channel, 1);
+ snprintf(newname, sizeof(newname), "DAHDI/%d:%d-%s", pri->trunkgroup,
+ new_chan->channel, pchan->no_b_channel ? "NO-MEDIA" : "1");
ast_change_name(new_chan->owner, newname);
new_chan->owner->tech_pvt = new_chan;
@@ -2714,6 +2725,8 @@
ast_copy_string(p->rdnis, rdnis, sizeof(p->rdnis));
}
+static int dahdi_new_pri_nobch_channel(struct sig_pri_pri *pri);
+
static struct sig_pri_callback dahdi_pri_callbacks =
{
.handle_dchan_exception = my_handle_dchan_exception,
@@ -2728,6 +2741,7 @@
.set_callerid = my_pri_set_callerid,
.set_dnid = my_pri_set_dnid,
.set_rdnis = my_pri_set_rdnis,
+ .new_nobch_intf = dahdi_new_pri_nobch_channel,
};
#endif /* defined(HAVE_PRI) */
@@ -4774,6 +4788,101 @@
#if defined(HAVE_PRI)
/*!
* \internal
+ * \brief Insert the given chan_dahdi interface structure into the no B channel list.
+ * \since 1.6.3
+ *
+ * \param pri sig_pri span control structure holding no B channel list.
+ * \param pvt chan_dahdi private interface structure to insert.
+ *
+ * \details
+ * The interface list is a doubly linked list sorted by the chan_dahdi channel number.
+ * Any duplicates are inserted after the existing entries.
+ *
+ * \note The new interface must not already be in the list.
+ *
+ * \return Nothing
+ */
+static void dahdi_nobch_insert(struct sig_pri_pri *pri, struct dahdi_pvt *pvt)
+{
+ struct dahdi_pvt *cur;
+
+ pvt->which_iflist = DAHDI_IFLIST_NO_B_CHAN;
+
+ /* Find place in middle of list for the new interface. */
+ for (cur = pri->no_b_chan_iflist; cur; cur = cur->next) {
+ if (pvt->channel < cur->channel) {
+ /* New interface goes before the current interface. */
+ pvt->prev = cur->prev;
+ pvt->next = cur;
+ if (cur->prev) {
+ /* Insert into the middle of the list. */
+ cur->prev->next = pvt;
+ } else {
+ /* Insert at head of list. */
+ pri->no_b_chan_iflist = pvt;
+ }
+ cur->prev = pvt;
+ return;
+ }
+ }
+
+ /* New interface goes onto the end of the list */
+ pvt->prev = pri->no_b_chan_end;
+ pvt->next = NULL;
+ if (pri->no_b_chan_end) {
+ ((struct dahdi_pvt *) pri->no_b_chan_end)->next = pvt;
+ }
+ pri->no_b_chan_end = pvt;
+ if (!pri->no_b_chan_iflist) {
+ /* List was empty */
+ pri->no_b_chan_iflist = pvt;
+ }
+}
+#endif /* defined(HAVE_PRI) */
+
+#if defined(HAVE_PRI)
+/*!
+ * \internal
+ * \brief Extract the given chan_dahdi interface structure from the no B channel list.
+ * \since 1.6.3
+ *
+ * \param pri sig_pri span control structure holding no B channel list.
+ * \param pvt chan_dahdi private interface structure to extract.
+ *
+ * \note
+ * The given interface structure can be either in the interface list or a stand alone
+ * structure that has not been put in the list if the next and prev pointers are NULL.
+ *
+ * \return Nothing
+ */
+static void dahdi_nobch_extract(struct sig_pri_pri *pri, struct dahdi_pvt *pvt)
+{
+ /* Extract from the forward chain. */
+ if (pvt->prev) {
+ pvt->prev->next = pvt->next;
+ } else if (pri->no_b_chan_iflist == pvt) {
+ /* Node is at the head of the list. */
+ pri->no_b_chan_iflist = pvt->next;
+ }
+
+ /* Extract from the reverse chain. */
+ if (pvt->next) {
+ pvt->next->prev = pvt->prev;
+ } else if (pri->no_b_chan_end == pvt) {
+ /* Node is at the end of the list. */
+ pri->no_b_chan_end = pvt->prev;
+ }
+
+ /* Node is no longer in the list. */
+ pvt->which_iflist = DAHDI_IFLIST_NONE;
+ pvt->prev = NULL;
+ pvt->next = NULL;
+}
+#endif /* defined(HAVE_PRI) */
+
+#if defined(HAVE_PRI)
+/*!
+ * \internal
* \brief Unlink the channel interface from the PRI private pointer array.
* \since 1.6.3
*
@@ -4817,6 +4926,13 @@
case DAHDI_IFLIST_MAIN:
dahdi_iflist_extract(p);
break;
+#if defined(HAVE_PRI)
+ case DAHDI_IFLIST_NO_B_CHAN:
+ if (p->pri) {
+ dahdi_nobch_extract(p->pri, p);
+ }
+ break;
+#endif /* defined(HAVE_PRI) */
}
if (p->sig_pvt) {
@@ -4866,6 +4982,10 @@
static void destroy_all_channels(void)
{
int chan;
+#if defined(HAVE_PRI)
+ unsigned span;
+ struct sig_pri_pri *pri;
+#endif /* defined(HAVE_PRI) */
struct dahdi_pvt *p;
while (num_restart_pending) {
@@ -4899,6 +5019,21 @@
}
ifcount = 0;
ast_mutex_unlock(&iflock);
+
+#if defined(HAVE_PRI)
+ /* Destroy all of the no B channel interface lists */
+ for (span = 0; span < NUM_SPANS; ++span) {
+ pri = &pris[span].pri;
+ ast_mutex_lock(&pri->lock);
+ while (pri->no_b_chan_iflist) {
+ p = pri->no_b_chan_iflist;
+
+ /* Free associated memory */
+ destroy_dahdi_pvt(p);
+ }
+ ast_mutex_unlock(&pri->lock);
+ }
+#endif /* defined(HAVE_PRI) */
}
#if defined(HAVE_PRI)
@@ -11390,7 +11525,7 @@
analog_config_complete(analog_p);
}
}
-#ifdef HAVE_PRI
+#if defined(HAVE_PRI)
else if (pchan != NULL) {
pchan->channel = tmp->channel;
pchan->hidecallerid = tmp->hidecallerid;
@@ -11405,7 +11540,17 @@
ast_copy_string(pchan->mohinterpret, tmp->mohinterpret, sizeof(pchan->mohinterpret));
pchan->stripmsd = tmp->stripmsd;
}
-#endif
+ if (tmp->channel == CHAN_PSEUDO) {
+ /*
+ * Save off pseudo channel buffer policy values for dynamic creation of
+ * no B channel interfaces.
+ */
+ dahdi_pseudo_parms.buf_no = tmp->buf_no;
+ dahdi_pseudo_parms.buf_policy = tmp->buf_policy;
+ dahdi_pseudo_parms.faxbuf_no = tmp->faxbuf_no;
+ dahdi_pseudo_parms.faxbuf_policy = tmp->faxbuf_policy;
+ }
+#endif /* defined(HAVE_PRI) */
}
if (tmp && !here) {
/* Add the new channel interface to the sorted channel interface list. */
@@ -11475,6 +11620,110 @@
return 0;
}
+
+#if defined(HAVE_PRI)
+/*!
+ * \internal
+ * \brief Create a no B channel interface.
+ * \since 1.6.3
+ *
+ * \param pri sig_pri span controller to add interface.
+ *
+ * \note Assumes the pri->lock is already obtained.
+ *
+ * \retval array-index into private pointer array on success.
+ * \retval -1 on error.
+ */
+static int dahdi_new_pri_nobch_channel(struct sig_pri_pri *pri)
+{
+ int pvt_idx;
+ int res;
+ unsigned idx;
+ struct dahdi_pvt *pvt;
+ struct sig_pri_chan *chan;
+ struct dahdi_bufferinfo bi;
+
+ static int nobch_channel = CHAN_PSEUDO;
+
+ /* Find spot in the private pointer array for new interface. */
+ for (pvt_idx = 0; pvt_idx < pri->numchans; ++pvt_idx) {
+ if (!pri->pvts[pvt_idx]) {
+ break;
+ }
+ }
+ if (pri->numchans == pvt_idx) {
+ if (MAX_CHANNELS <= pvt_idx) {
+ ast_log(LOG_ERROR, "Unable to add a no-B-channel interface!\n");
+ return -1;
+ }
+
+ /* Add new spot to the private pointer array. */
+ pri->pvts[pvt_idx] = NULL;
+ ++pri->numchans;
+ }
+
+ pvt = ast_calloc(1, sizeof(*pvt));
+ if (!pvt) {
+ return -1;
+ }
+ ast_mutex_init(&pvt->lock);
+ for (idx = 0; idx < ARRAY_LEN(pvt->subs); ++idx) {
+ pvt->subs[idx].dfd = -1;
+ }
+ pvt->buf_no = dahdi_pseudo_parms.buf_no;
+ pvt->buf_policy = dahdi_pseudo_parms.buf_policy;
+ pvt->faxbuf_no = dahdi_pseudo_parms.faxbuf_no;
+ pvt->faxbuf_policy = dahdi_pseudo_parms.faxbuf_policy;
+
+ chan = sig_pri_chan_new(pvt, &dahdi_pri_callbacks, pri, 0, 0, 0);
+ if (!chan) {
+ destroy_dahdi_pvt(pvt);
+ return -1;
+ }
+ chan->no_b_channel = 1;
+
+ pvt->sig = pri->sig;
+ pvt->pri = pri;
+ pvt->sig_pvt = chan;
+ pri->pvts[pvt_idx] = chan;
+
+ pvt->subs[SUB_REAL].dfd = dahdi_open("/dev/dahdi/pseudo");
+ if (pvt->subs[SUB_REAL].dfd < 0) {
+ ast_log(LOG_ERROR, "Unable to open no B channel interface pseudo channel: %s\n",
+ strerror(errno));
+ destroy_dahdi_pvt(pvt);
+ return -1;
+ }
+ memset(&bi, 0, sizeof(bi));
+ res = ioctl(pvt->subs[SUB_REAL].dfd, DAHDI_GET_BUFINFO, &bi);
+ if (!res) {
+ pvt->bufsize = bi.bufsize;
+ bi.txbufpolicy = pvt->buf_policy;
+ bi.rxbufpolicy = pvt->buf_policy;
+ bi.numbufs = pvt->buf_no;
+ res = ioctl(pvt->subs[SUB_REAL].dfd, DAHDI_SET_BUFINFO, &bi);
+ if (res < 0) {
+ ast_log(LOG_WARNING,
+ "Unable to set buffer policy on no B channel interface: %s\n",
+ strerror(errno));
+ }
+ } else
+ ast_log(LOG_WARNING,
+ "Unable to check buffer policy on no B channel interface: %s\n",
+ strerror(errno));
+
+ --nobch_channel;
+ if (CHAN_PSEUDO < nobch_channel) {
+ nobch_channel = CHAN_PSEUDO - 1;
+ }
+ pvt->channel = nobch_channel;
+ chan->channel = pvt->channel;
+
+ dahdi_nobch_insert(pri, pvt);
+
+ return pvt_idx;
+}
+#endif /* defined(HAVE_PRI) */
/* This function can *ONLY* be used for copying pseudo (CHAN_PSEUDO) private
structures; it makes no attempt to safely copy regular channel private
Modified: team/rmudgett/dahdi_facility/channels/sig_pri.c
URL: http://svn.asterisk.org/svn-view/asterisk/team/rmudgett/dahdi_facility/channels/sig_pri.c?view=diff&rev=218691&r1=218690&r2=218691
==============================================================================
--- team/rmudgett/dahdi_facility/channels/sig_pri.c (original)
+++ team/rmudgett/dahdi_facility/channels/sig_pri.c Tue Sep 15 14:51:27 2009
@@ -67,9 +67,11 @@
#define DCHAN_NOTINALARM (1 << 0)
#define DCHAN_UP (1 << 1)
-#define PRI_CHANNEL(p) ((p) & 0xff)
-#define PRI_SPAN(p) (((p) >> 8) & 0xff)
-#define PRI_EXPLICIT(p) (((p) >> 16) & 0x01)
+#define PRI_CHANNEL(p) ((p) & 0xff)
+#define PRI_SPAN(p) (((p) >> 8) & 0xff)
+#define PRI_EXPLICIT(p) (((p) >> 16) & 0x01)
+#define PRI_CIS_CALL(p) (((p) >> 17) & 0x01) /* Call is using the D channel only. */
+#define PRI_HELD_CALL(p) (((p) >> 18) & 0x01)
#define DCHAN_AVAILABLE (DCHAN_NOTINALARM | DCHAN_UP)
@@ -659,74 +661,126 @@
pri_queue_frame(p, &f, pri);
}
-static int pri_find_principle(struct sig_pri_pri *pri, int channel)
+static int pri_find_principle(struct sig_pri_pri *pri, int channel, q931_call *call)
{
int x;
- int span = PRI_SPAN(channel);
- int principle = -1;
- int explicit_ds1 = PRI_EXPLICIT(channel);
+ int span;
+ int principle;
+
+ if (channel < 0) {
+ /* Channel is not picked yet. */
+ return -1;
+ }
+
+ if (PRI_HELD_CALL(channel)) {
+ if (!call) {
+ /* Cannot find a held call without a call. */
+ return -1;
+ }
+ principle = -1;
+ for (x = 0; x < pri->numchans; ++x) {
+ if (pri->pvts[x]
+ && pri->pvts[x]->call == call) {
+ principle = x;
+ break;
+ }
+ }
+ return principle;
+ }
+
+ span = PRI_SPAN(channel);
+ if (!PRI_EXPLICIT(channel)) {
+ int index;
+
+ index = pri_active_dchan_index(pri);
+ if (index == -1) {
+ return -1;
+ }
+ span = pri->dchan_logical_span[index];
+ }
+
channel = PRI_CHANNEL(channel);
-
- if (!explicit_ds1) {
- int index = pri_active_dchan_index(pri);
- if (index == -1)
+ principle = -1;
+ for (x = 0; x < pri->numchans; x++) {
+ if (pri->pvts[x]
+ && pri->pvts[x]->prioffset == channel
+ && pri->pvts[x]->logicalspan == span
+ && !pri->pvts[x]->no_b_channel) {
+ principle = x;
+ break;
+ }
+ }
+
+ return principle;
+}
+
+static int pri_fixup_principle(struct sig_pri_pri *pri, int principle, q931_call *call)
+{
+ int x;
+
+ if (principle < 0 || pri->numchans <= principle) {
+ /* Out of rannge */
+ return -1;
+ }
+ if (!call) {
+ /* No call */
+ return principle;
+ }
+ if (pri->pvts[principle] && pri->pvts[principle]->call == call) {
+ /* Call is already on the specified principle. */
+ return principle;
+ }
+
+ /* Find the old principle location. */
+ for (x = 0; x < pri->numchans; x++) {
+ struct sig_pri_chan *new_chan;
+ struct sig_pri_chan *old_chan;
+
+ if (!pri->pvts[x] || pri->pvts[x]->call != call) {
+ continue;
+ }
+
+ /* Found our call */
+ new_chan = pri->pvts[principle];
+ old_chan = pri->pvts[x];
+
+ ast_verb(3, "Moving call from channel %d to channel %d\n",
+ old_chan->channel, new_chan->channel);
+ if (new_chan->owner) {
+ ast_log(LOG_WARNING,
+ "Can't fix up channel from %d to %d because %d is already in use\n",
+ old_chan->channel, new_chan->channel, new_chan->channel);
return -1;
- span = pri->dchan_logical_span[index];
- }
-
- for (x = 0; x < pri->numchans; x++) {
- if (pri->pvts[x] && (pri->pvts[x]->prioffset == channel) && (pri->pvts[x]->logicalspan == span)) {
- principle = x;
- break;
- }
- }
-
- return principle;
-}
-
-static int pri_fixup_principle(struct sig_pri_pri *pri, int principle, q931_call *c)
-{
- int x;
-
- if (!c) {
- if (principle < 0)
- return -1;
+ }
+
+ sig_pri_fixup_chans(old_chan, new_chan);
+
+ /* Fix it all up now */
+ new_chan->owner = old_chan->owner;
+ old_chan->owner = NULL;
+
+ new_chan->call = old_chan->call;
+ old_chan->call = NULL;
+
+ if (new_chan->no_b_channel) {
+ /* Copy the real channel configuration to the no B channel interface. */
+ new_chan->hidecallerid = old_chan->hidecallerid;
+ new_chan->hidecalleridname = old_chan->hidecalleridname;
+ new_chan->immediate = old_chan->immediate;
+ new_chan->priexclusive = old_chan->priexclusive;
+ new_chan->priindication_oob = old_chan->priindication_oob;
+ new_chan->use_callerid = old_chan->use_callerid;
+ new_chan->use_callingpres = old_chan->use_callingpres;
+ new_chan->stripmsd = old_chan->stripmsd;
+ strcpy(new_chan->context, old_chan->context);
+ strcpy(new_chan->mohinterpret, old_chan->mohinterpret);
+
+ /* Become a member of the old channel span/trunk-group. */
+ new_chan->logicalspan = old_chan->logicalspan;
+ new_chan->mastertrunkgroup = old_chan->mastertrunkgroup;
+ }
+
return principle;
- }
- if ((principle > -1) &&
- (principle < pri->numchans) &&
- (pri->pvts[principle]) &&
- (pri->pvts[principle]->call == c))
- return principle;
- /* First, check for other bearers */
- for (x = 0; x < pri->numchans; x++) {
- if (!pri->pvts[x])
- continue;
- if (pri->pvts[x]->call == c) {
- /* Found our call */
- if (principle != x) {
- struct sig_pri_chan *new_chan = pri->pvts[principle];
- struct sig_pri_chan *old_chan = pri->pvts[x];
-
- ast_verb(3, "Moving call from channel %d to channel %d\n",
- old_chan->channel, new_chan->channel);
- if (new_chan->owner) {
- ast_log(LOG_WARNING, "Can't fix up channel from %d to %d because %d is already in use\n",
- old_chan->channel, new_chan->channel, new_chan->channel);
- return -1;
- }
-
- sig_pri_fixup_chans(old_chan, new_chan);
- /* Fix it all up now */
- new_chan->owner = old_chan->owner;
- old_chan->owner = NULL;
-
- new_chan->call = old_chan->call;
- old_chan->call = NULL;
-
- }
- return principle;
- }
}
ast_log(LOG_WARNING, "Call specified, but not found?\n");
return -1;
@@ -787,10 +841,11 @@
#endif
do {
pri->resetpos++;
- } while ((pri->resetpos < pri->numchans) &&
- (!pri->pvts[pri->resetpos] ||
- pri->pvts[pri->resetpos]->call ||
- pri->pvts[pri->resetpos]->resetting));
+ } while (pri->resetpos < pri->numchans
+ && (!pri->pvts[pri->resetpos]
+ || pri->pvts[pri->resetpos]->no_b_channel
+ || pri->pvts[pri->resetpos]->call
+ || pri->pvts[pri->resetpos]->resetting));
if (pri->resetpos < pri->numchans) {
#ifdef HAVE_PRI_SERVICE_MESSAGES
char db_chan_name[20], db_answer[5], state;
@@ -834,7 +889,10 @@
break;
if (!backwards && (x >= pri->numchans))
break;
- if (pri->pvts[x] && !pri->pvts[x]->inalarm && !pri->pvts[x]->owner) {
+ if (pri->pvts[x]
+ && !pri->pvts[x]->no_b_channel
+ && !pri->pvts[x]->inalarm
+ && !pri->pvts[x]->owner) {
ast_debug(1, "Found empty available channel %d/%d\n",
pri->pvts[x]->logicalspan, pri->pvts[x]->prioffset);
return x;
@@ -1303,8 +1361,10 @@
haveidles = 0;
activeidles = 0;
for (x = pri->numchans; x >= 0; x--) {
- if (pri->pvts[x] && !pri->pvts[x]->owner &&
- !pri->pvts[x]->call) {
+ if (pri->pvts[x]
+ && !pri->pvts[x]->owner
+ && !pri->pvts[x]->call
+ && !pri->pvts[x]->no_b_channel) {
if (haveidles < pri->minunused) {
haveidles++;
} else if (!pri->pvts[x]->resetting) {
@@ -1485,7 +1545,7 @@
break;
case PRI_EVENT_RESTART:
if (e->restart.channel > -1) {
- chanpos = pri_find_principle(pri, e->restart.channel);
+ chanpos = pri_find_principle(pri, e->restart.channel, NULL);
if (chanpos < 0)
ast_log(LOG_WARNING, "Restart requested on odd/unavailable channel number %d/%d on span %d\n",
PRI_SPAN(e->restart.channel), PRI_CHANNEL(e->restart.channel), pri->span);
@@ -1541,7 +1601,7 @@
}
break;
case PRI_EVENT_KEYPAD_DIGIT:
- chanpos = pri_find_principle(pri, e->digit.channel);
+ chanpos = pri_find_principle(pri, e->digit.channel, e->digit.call);
if (chanpos < 0) {
ast_log(LOG_WARNING, "KEYPAD_DIGITs received on unconfigured channel %d/%d span %d\n",
PRI_SPAN(e->digit.channel), PRI_CHANNEL(e->digit.channel), pri->span);
@@ -1571,7 +1631,7 @@
break;
case PRI_EVENT_INFO_RECEIVED:
- chanpos = pri_find_principle(pri, e->ring.channel);
+ chanpos = pri_find_principle(pri, e->ring.channel, e->ring.call);
if (chanpos < 0) {
ast_log(LOG_WARNING, "INFO received on unconfigured channel %d/%d span %d\n",
PRI_SPAN(e->ring.channel), PRI_CHANNEL(e->ring.channel), pri->span);
@@ -1601,7 +1661,7 @@
break;
#ifdef HAVE_PRI_SERVICE_MESSAGES
case PRI_EVENT_SERVICE:
- chanpos = pri_find_principle(pri, e->service.channel);
+ chanpos = pri_find_principle(pri, e->service.channel, NULL);
if (chanpos < 0) {
ast_log(LOG_WARNING, "Received service change status %d on unconfigured channel %d/%d span %d\n",
e->service_ack.changestatus, PRI_SPAN(e->service_ack.channel), PRI_CHANNEL(e->service_ack.channel), pri->span);
@@ -1645,7 +1705,7 @@
}
break;
case PRI_EVENT_SERVICE_ACK:
- chanpos = pri_find_principle(pri, e->service_ack.channel);
+ chanpos = pri_find_principle(pri, e->service_ack.channel, NULL);
if (chanpos < 0) {
ast_log(LOG_WARNING, "Received service acknowledge change status '%d' on unconfigured channel %d/%d span %d\n",
e->service_ack.changestatus, PRI_SPAN(e->service_ack.channel), PRI_CHANNEL(e->service_ack.channel), pri->span);
@@ -1668,7 +1728,7 @@
if (e->ring.channel == -1)
chanpos = pri_find_empty_chan(pri, 1);
else
- chanpos = pri_find_principle(pri, e->ring.channel);
+ 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",
@@ -1913,7 +1973,7 @@
}
break;
case PRI_EVENT_RINGING:
- chanpos = pri_find_principle(pri, e->ringing.channel);
+ chanpos = pri_find_principle(pri, e->ringing.channel, e->ringing.call);
if (chanpos < 0) {
ast_log(LOG_WARNING, "Ringing requested on unconfigured channel %d/%d span %d\n",
PRI_SPAN(e->ringing.channel), PRI_CHANNEL(e->ringing.channel), pri->span);
@@ -1951,7 +2011,7 @@
break;
case PRI_EVENT_PROGRESS:
/* Get chan value if e->e is not PRI_EVNT_RINGING */
- chanpos = pri_find_principle(pri, e->proceeding.channel);
+ chanpos = pri_find_principle(pri, e->proceeding.channel, e->proceeding.call);
if (chanpos > -1) {
sig_pri_lock_private(pri->pvts[chanpos]);
sig_pri_handle_subcmds(pri, chanpos, e->e, e->proceeding.channel,
@@ -2000,7 +2060,7 @@
}
break;
case PRI_EVENT_PROCEEDING:
- chanpos = pri_find_principle(pri, e->proceeding.channel);
+ chanpos = pri_find_principle(pri, e->proceeding.channel, e->proceeding.call);
if (chanpos > -1) {
sig_pri_lock_private(pri->pvts[chanpos]);
sig_pri_handle_subcmds(pri, chanpos, e->e, e->proceeding.channel,
@@ -2029,7 +2089,7 @@
}
break;
case PRI_EVENT_FACILITY:
- chanpos = pri_find_principle(pri, e->facility.channel);
+ chanpos = pri_find_principle(pri, e->facility.channel, e->facility.call);
if (chanpos < 0) {
ast_log(LOG_WARNING, "Facility requested on unconfigured channel %d/%d span %d\n",
PRI_SPAN(e->facility.channel), PRI_CHANNEL(e->facility.channel), pri->span);
@@ -2047,7 +2107,7 @@
}
break;
case PRI_EVENT_ANSWER:
- chanpos = pri_find_principle(pri, e->answer.channel);
+ chanpos = pri_find_principle(pri, e->answer.channel, e->answer.call);
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);
@@ -2085,7 +2145,7 @@
}
break;
case PRI_EVENT_HANGUP:
- chanpos = pri_find_principle(pri, e->hangup.channel);
+ chanpos = pri_find_principle(pri, e->hangup.channel, e->hangup.call);
if (chanpos < 0) {
ast_log(LOG_WARNING, "Hangup requested on unconfigured channel %d/%d span %d\n",
PRI_SPAN(e->hangup.channel), PRI_CHANNEL(e->hangup.channel), pri->span);
@@ -2160,7 +2220,7 @@
}
break;
case PRI_EVENT_HANGUP_REQ:
- chanpos = pri_find_principle(pri, e->hangup.channel);
+ chanpos = pri_find_principle(pri, e->hangup.channel, e->hangup.call);
if (chanpos < 0) {
ast_log(LOG_WARNING, "Hangup REQ requested on unconfigured channel %d/%d span %d\n",
PRI_SPAN(e->hangup.channel), PRI_CHANNEL(e->hangup.channel), pri->span);
@@ -2228,7 +2288,7 @@
}
break;
case PRI_EVENT_HANGUP_ACK:
- chanpos = pri_find_principle(pri, e->hangup.channel);
+ chanpos = pri_find_principle(pri, e->hangup.channel, e->hangup.call);
if (chanpos < 0) {
ast_log(LOG_WARNING, "Hangup ACK requested on unconfigured channel number %d/%d span %d\n",
PRI_SPAN(e->hangup.channel), PRI_CHANNEL(e->hangup.channel), pri->span);
@@ -2264,7 +2324,7 @@
ast_log(LOG_WARNING, "PRI Error on span %d: %s\n", pri->trunkgroup, e->err.err);
break;
case PRI_EVENT_RESTART_ACK:
- chanpos = pri_find_principle(pri, e->restartack.channel);
+ chanpos = pri_find_principle(pri, e->restartack.channel, NULL);
if (chanpos < 0) {
/* Sometime switches (e.g. I421 / British Telecom) don't give us the
channel number, so we have to figure it out... This must be why
@@ -2311,7 +2371,7 @@
}
break;
case PRI_EVENT_SETUP_ACK:
- chanpos = pri_find_principle(pri, e->setup_ack.channel);
+ chanpos = pri_find_principle(pri, e->setup_ack.channel, e->setup_ack.call);
if (chanpos < 0) {
ast_log(LOG_WARNING, "Received SETUP_ACKNOWLEDGE on unconfigured channel %d/%d span %d\n",
PRI_SPAN(e->setup_ack.channel), PRI_CHANNEL(e->setup_ack.channel), pri->span);
@@ -2334,7 +2394,11 @@
}
break;
case PRI_EVENT_NOTIFY:
- chanpos = pri_find_principle(pri, e->notify.channel);
+#if defined(HAVE_PRI) /* BUGBUG */
+ chanpos = pri_find_principle(pri, e->notify.channel, e->notify.call);
+#else
+ chanpos = pri_find_principle(pri, e->notify.channel, NULL);
+#endif /* !defined(HAVE_PRI_CALL_HOLD) */
if (chanpos < 0) {
ast_log(LOG_WARNING, "Received NOTIFY on unconfigured channel %d/%d span %d\n",
PRI_SPAN(e->notify.channel), PRI_CHANNEL(e->notify.channel), pri->span);
@@ -2363,6 +2427,36 @@
sig_pri_unlock_private(pri->pvts[chanpos]);
}
break;
+#if defined(HAVE_PRI) /* BUGBUG */
+ case PRI_EVENT_HOLD:
+/* BUGBUG */
+ break;
+#endif /* defined(HAVE_PRI_CALL_HOLD) */
+#if defined(HAVE_PRI) /* BUGBUG */
+ case PRI_EVENT_HOLD_ACK:
+/* BUGBUG */
+ break;
+#endif /* defined(HAVE_PRI_CALL_HOLD) */
+#if defined(HAVE_PRI) /* BUGBUG */
+ case PRI_EVENT_HOLD_REJ:
+/* BUGBUG */
+ break;
+#endif /* defined(HAVE_PRI_CALL_HOLD) */
+#if defined(HAVE_PRI) /* BUGBUG */
+ case PRI_EVENT_RETRIEVE:
+/* BUGBUG */
+ break;
+#endif /* defined(HAVE_PRI_CALL_HOLD) */
+#if defined(HAVE_PRI) /* BUGBUG */
+ case PRI_EVENT_RETRIEVE_ACK:
+/* BUGBUG */
+ break;
+#endif /* defined(HAVE_PRI_CALL_HOLD) */
+#if defined(HAVE_PRI) /* BUGBUG */
+ case PRI_EVENT_RETRIEVE_REJ:
+/* BUGBUG */
+ break;
+#endif /* defined(HAVE_PRI_CALL_HOLD) */
default:
ast_debug(1, "Event: %d\n", e->e);
}
@@ -2805,7 +2899,7 @@
chan->_softhangup |= AST_SOFTHANGUP_DEV;
res = 0;
} else if (!p->progress && p->pri && !p->outgoing) {
- if (p->pri) {
+ if (p->pri->pri) {
if (!pri_grab(p, p->pri)) {
#ifdef HAVE_PRI_PROG_W_CAUSE
pri_progress_with_cause(p->pri->pri,p->call, PVT_TO_CHANNEL(p), 1, PRI_CAUSE_SWITCH_CONGESTION); /* cause = 42 */
@@ -2889,30 +2983,28 @@
int sig_pri_available(struct sig_pri_chan *p, int channelmatch, ast_group_t groupmatch, int *reason, int *channelmatched, int *groupmatched)
{
- /* If no owner definitely available */
- if (!p->owner) {
- /* Trust PRI */
- if (p->pri) {
+ /* If no owner and interface has a B channel then likely available */
+ if (!p->owner && !p->no_b_channel && p->pri) {
#ifdef HAVE_PRI_SERVICE_MESSAGES
- char db_chan_name[20], db_answer[5], state;
- int why = 0;
-
- snprintf(db_chan_name, sizeof(db_chan_name), "%s/%d:%d", dahdi_db, p->pri->span, p->channel);
- if (!ast_db_get(db_chan_name, SRVST_DBKEY, db_answer, sizeof(db_answer))) {
- sscanf(db_answer, "%1c:%30d", &state, &why);
+ char db_chan_name[20], db_answer[5], state;
+ int why = 0;
+
+ snprintf(db_chan_name, sizeof(db_chan_name), "%s/%d:%d", dahdi_db, p->pri->span, p->channel);
+ if (!ast_db_get(db_chan_name, SRVST_DBKEY, db_answer, sizeof(db_answer))) {
+ sscanf(db_answer, "%1c:%30d", &state, &why);
+ }
+ if (p->resetting || p->call || why) {
+ if (why) {
+ *reason = AST_CAUSE_REQUESTED_CHAN_UNAVAIL;
}
- if ((p->resetting || p->call) || (why)) {
- if (why) {
- *reason = AST_CAUSE_REQUESTED_CHAN_UNAVAIL;
- }
+ return 0;
+ }
#else
- if (p->resetting || p->call) {
-#endif
- return 0;
- } else {
- return 1;
- }
- }
+ if (p->resetting || p->call) {
+ return 0;
+ }
+#endif
+ return 1;
}
return 0;
Modified: team/rmudgett/dahdi_facility/channels/sig_pri.h
URL: http://svn.asterisk.org/svn-view/asterisk/team/rmudgett/dahdi_facility/channels/sig_pri.h?view=diff&rev=218691&r1=218690&r2=218691
==============================================================================
--- team/rmudgett/dahdi_facility/channels/sig_pri.h (original)
+++ team/rmudgett/dahdi_facility/channels/sig_pri.h Tue Sep 15 14:51:27 2009
@@ -75,6 +75,7 @@
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);
+ int (* const new_nobch_intf)(struct sig_pri_pri *pri);
};
#define NUM_DCHANS 4 /*!< No more than 4 d-channels */
@@ -154,6 +155,7 @@
unsigned int outgoing:1;
unsigned int digital:1;
+ unsigned int no_b_channel:1; /*!< TRUE if this interface has no B channel. (call hold and call waiting) */
struct ast_channel *owner;
@@ -216,6 +218,16 @@
/* Everything after here is internally set */
struct pri *dchans[NUM_DCHANS]; /*!< Actual d-channels */
struct pri *pri; /*!< Currently active D-channel */
+ /*!
+ * List of private structures of the user of this module for no B channel
+ * interfaces. (hold and call waiting interfaces)
+ */
+ void *no_b_chan_iflist;
+ /*!
+ * List of private structures of the user of this module for no B channel
+ * interfaces. (hold and call waiting interfaces)
+ */
+ void *no_b_chan_end;
int numchans; /*!< Num of channels we represent */
struct sig_pri_chan *pvts[MAX_CHANNELS]; /*!< Member channel pvt structs */
pthread_t master; /*!< Thread of master */
More information about the asterisk-commits
mailing list