summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJoshua Colp <jcolp@digium.com>2008-04-10 20:28:40 +0000
committerJoshua Colp <jcolp@digium.com>2008-04-10 20:28:40 +0000
commita08c4b2064467ba942543dfb1ebed06498aca2d1 (patch)
tree66c2fcd2afb22bd9f95a32ad351b66f423a38af7
parentd13b45564b2c4dc7efc1539fa53d8dd4e7929365 (diff)
A 'b' option has been added which causes chan_local to return the actual channel that is behind it when queried. This is useful for transfer scenarios as the actual channel will be transferred, not the Local channel. If you have been using Local channels as queue members and having issues when the agent did a blind transfer this option may solve the issue.
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@114049 65c4cc65-6c06-0410-ace0-fbb531ad65f3
-rw-r--r--CHANGES3
-rw-r--r--channels/chan_local.c28
2 files changed, 31 insertions, 0 deletions
diff --git a/CHANGES b/CHANGES
index efc9c82d5..338b98661 100644
--- a/CHANGES
+++ b/CHANGES
@@ -257,6 +257,9 @@ Local channel changes
SIP call to Voicemail by putting a Local channel in the middle. This
feature is enabled by using the 'j' option in the Dial string to the Local
channel in conjunction with the existing 'n' option for local channels.
+ * A 'b' option has been added which causes chan_local to return the actual channel
+ that is behind it when queried. This is useful for transfer scenarios as the
+ actual channel will be transferred, not the Local channel.
Zaptel channel driver (chan_zap) Changes
----------------------------------------
diff --git a/channels/chan_local.c b/channels/chan_local.c
index ffd25bc33..e79c82184 100644
--- a/channels/chan_local.c
+++ b/channels/chan_local.c
@@ -74,6 +74,7 @@ static int local_fixup(struct ast_channel *oldchan, struct ast_channel *newchan)
static int local_sendhtml(struct ast_channel *ast, int subclass, const char *data, int datalen);
static int local_sendtext(struct ast_channel *ast, const char *text);
static int local_devicestate(void *data);
+static struct ast_channel *local_bridgedchannel(struct ast_channel *chan, struct ast_channel *bridge);
/* PBX interface structure for channel registration */
static const struct ast_channel_tech local_tech = {
@@ -95,6 +96,7 @@ static const struct ast_channel_tech local_tech = {
.send_html = local_sendhtml,
.send_text = local_sendtext,
.devicestate = local_devicestate,
+ .bridged_channel = local_bridgedchannel,
};
struct local_pvt {
@@ -116,6 +118,7 @@ struct local_pvt {
#define LOCAL_ALREADY_MASQED (1 << 2) /*!< Already masqueraded */
#define LOCAL_LAUNCHED_PBX (1 << 3) /*!< PBX was launched */
#define LOCAL_NO_OPTIMIZATION (1 << 4) /*!< Do not optimize using masquerading */
+#define LOCAL_BRIDGE (1 << 5) /*!< Report back the "true" channel as being bridged to */
static AST_LIST_HEAD_STATIC(locals, local_pvt);
@@ -167,6 +170,28 @@ static struct local_pvt *local_pvt_destroy(struct local_pvt *pvt)
return NULL;
}
+/*! \brief Return the bridged channel of a Local channel */
+static struct ast_channel *local_bridgedchannel(struct ast_channel *chan, struct ast_channel *bridge)
+{
+ struct local_pvt *p = bridge->tech_pvt;
+ struct ast_channel *bridged = bridge;
+
+ ast_mutex_lock(&p->lock);
+
+ if (ast_test_flag(p, LOCAL_BRIDGE)) {
+ /* Find the opposite channel */
+ bridged = (bridge == p->owner ? p->chan : p->owner);
+
+ /* Now see if the opposite channel is bridged to anything */
+ if (bridged->_bridge)
+ bridged = bridged->_bridge;
+ }
+
+ ast_mutex_unlock(&p->lock);
+
+ return bridged;
+}
+
static int local_queue_frame(struct local_pvt *p, int isoutbound, struct ast_frame *f, struct ast_channel *us)
{
struct ast_channel *other = NULL;
@@ -601,6 +626,9 @@ static struct local_pvt *local_alloc(const char *data, int format)
"to use the 'j' option to enable the jitterbuffer\n");
}
}
+ if (strchr(opts, 'b')) {
+ ast_set_flag(tmp, LOCAL_BRIDGE);
+ }
}
/* Look for a context */