aboutsummaryrefslogtreecommitdiffstats
path: root/channels
diff options
context:
space:
mode:
Diffstat (limited to 'channels')
-rw-r--r--channels/chan_agent.c18
-rw-r--r--channels/chan_alsa.c12
-rw-r--r--channels/chan_bridge.c8
-rw-r--r--channels/chan_console.c14
-rw-r--r--channels/chan_dahdi.c58
-rw-r--r--channels/chan_gtalk.c12
-rw-r--r--channels/chan_h323.c12
-rw-r--r--channels/chan_iax2.c74
-rw-r--r--channels/chan_jingle.c12
-rw-r--r--channels/chan_local.c12
-rw-r--r--channels/chan_mgcp.c16
-rw-r--r--channels/chan_misdn.c14
-rw-r--r--channels/chan_multicast_rtp.c6
-rw-r--r--channels/chan_nbs.c10
-rw-r--r--channels/chan_oss.c13
-rw-r--r--channels/chan_phone.c18
-rw-r--r--channels/chan_sip.c55
-rw-r--r--channels/chan_skinny.c42
-rw-r--r--channels/chan_unistim.c16
-rw-r--r--channels/chan_usbradio.c13
-rw-r--r--channels/chan_vpb.cc24
-rw-r--r--channels/sig_analog.c20
-rw-r--r--channels/sig_analog.h4
-rw-r--r--channels/sig_pri.c14
-rw-r--r--channels/sig_pri.h4
25 files changed, 290 insertions, 211 deletions
diff --git a/channels/chan_agent.c b/channels/chan_agent.c
index f8205d4cd..a31a12fdf 100644
--- a/channels/chan_agent.c
+++ b/channels/chan_agent.c
@@ -310,7 +310,7 @@ static AST_LIST_HEAD_STATIC(agents, agent_pvt); /*!< Holds the list of agents (l
} while(0)
/*--- Forward declarations */
-static struct ast_channel *agent_request(const char *type, int format, void *data, int *cause);
+static struct ast_channel *agent_request(const char *type, int format, const struct ast_channel *requestor, void *data, int *cause);
static int agent_devicestate(void *data);
static int agent_digit_begin(struct ast_channel *ast, char digit);
static int agent_digit_end(struct ast_channel *ast, char digit, unsigned int duration);
@@ -986,7 +986,7 @@ static struct ast_channel *agent_bridgedchannel(struct ast_channel *chan, struct
}
/*! \brief Create new agent channel */
-static struct ast_channel *agent_new(struct agent_pvt *p, int state)
+static struct ast_channel *agent_new(struct agent_pvt *p, int state, const char *linkedid)
{
struct ast_channel *tmp;
int alreadylocked;
@@ -997,9 +997,9 @@ static struct ast_channel *agent_new(struct agent_pvt *p, int state)
}
#endif
if (p->pending)
- tmp = ast_channel_alloc(0, state, 0, 0, "", p->chan ? p->chan->exten:"", p->chan ? p->chan->context:"", 0, "Agent/P%s-%d", p->agent, (int) ast_random() & 0xffff);
+ tmp = ast_channel_alloc(0, state, 0, 0, "", p->chan ? p->chan->exten:"", p->chan ? p->chan->context:"", linkedid, 0, "Agent/P%s-%d", p->agent, (int) ast_random() & 0xffff);
else
- tmp = ast_channel_alloc(0, state, 0, 0, "", p->chan ? p->chan->exten:"", p->chan ? p->chan->context:"", 0, "Agent/%s", p->agent);
+ tmp = ast_channel_alloc(0, state, 0, 0, "", p->chan ? p->chan->exten:"", p->chan ? p->chan->context:"", linkedid, 0, "Agent/%s", p->agent);
if (!tmp) {
ast_log(LOG_WARNING, "Unable to allocate agent channel structure\n");
return NULL;
@@ -1249,7 +1249,7 @@ static int check_availability(struct agent_pvt *newlyavailable, int needlock)
if (!p->abouttograb && p->pending && ((p->group && (newlyavailable->group & p->group)) || !strcmp(p->agent, newlyavailable->agent))) {
ast_debug(1, "Call '%s' looks like a winner for agent '%s'\n", p->owner->name, newlyavailable->agent);
/* We found a pending call, time to merge */
- chan = agent_new(newlyavailable, AST_STATE_DOWN);
+ chan = agent_new(newlyavailable, AST_STATE_DOWN, p->owner ? p->owner->linkedid : NULL);
parent = p->owner;
p->abouttograb = 1;
ast_mutex_unlock(&p->lock);
@@ -1334,7 +1334,7 @@ static int check_beep(struct agent_pvt *newlyavailable, int needlock)
}
/*! \brief Part of the Asterisk PBX interface */
-static struct ast_channel *agent_request(const char *type, int format, void *data, int *cause)
+static struct ast_channel *agent_request(const char *type, int format, const struct ast_channel* requestor, void *data, int *cause)
{
struct agent_pvt *p;
struct ast_channel *chan = NULL;
@@ -1367,7 +1367,7 @@ static struct ast_channel *agent_request(const char *type, int format, void *dat
/* Agent must be registered, but not have any active call, and not be in a waiting state */
if (!p->owner && p->chan) {
/* Fixed agent */
- chan = agent_new(p, AST_STATE_DOWN);
+ chan = agent_new(p, AST_STATE_DOWN, requestor ? requestor->linkedid : NULL);
}
if (chan) {
ast_mutex_unlock(&p->lock);
@@ -1390,7 +1390,7 @@ static struct ast_channel *agent_request(const char *type, int format, void *dat
/* Agent must be registered, but not have any active call, and not be in a waiting state */
if (!p->owner && p->chan) {
/* Could still get a fixed agent */
- chan = agent_new(p, AST_STATE_DOWN);
+ chan = agent_new(p, AST_STATE_DOWN, requestor ? requestor->linkedid : NULL);
}
if (chan) {
ast_mutex_unlock(&p->lock);
@@ -1409,7 +1409,7 @@ static struct ast_channel *agent_request(const char *type, int format, void *dat
ast_debug(1, "Creating place holder for '%s'\n", s);
p = add_agent(data, 1);
p->group = groupmatch;
- chan = agent_new(p, AST_STATE_DOWN);
+ chan = agent_new(p, AST_STATE_DOWN, requestor ? requestor->linkedid : NULL);
if (!chan)
ast_log(LOG_WARNING, "Weird... Fix this to drop the unused pending agent\n");
} else {
diff --git a/channels/chan_alsa.c b/channels/chan_alsa.c
index e1fe2b3fe..48d718682 100644
--- a/channels/chan_alsa.c
+++ b/channels/chan_alsa.c
@@ -130,7 +130,7 @@ static int writedev = -1;
static int autoanswer = 1;
-static struct ast_channel *alsa_request(const char *type, int format, void *data, int *cause);
+static struct ast_channel *alsa_request(const char *type, int format, const struct ast_channel *requestor, void *data, int *cause);
static int alsa_digit(struct ast_channel *c, char digit, unsigned int duration);
static int alsa_text(struct ast_channel *c, const char *text);
static int alsa_hangup(struct ast_channel *c);
@@ -532,11 +532,11 @@ static int alsa_indicate(struct ast_channel *chan, int cond, const void *data, s
return res;
}
-static struct ast_channel *alsa_new(struct chan_alsa_pvt *p, int state)
+static struct ast_channel *alsa_new(struct chan_alsa_pvt *p, int state, const char *linkedid)
{
struct ast_channel *tmp = NULL;
- if (!(tmp = ast_channel_alloc(1, state, 0, 0, "", p->exten, p->context, 0, "ALSA/%s", indevname)))
+ if (!(tmp = ast_channel_alloc(1, state, 0, 0, "", p->exten, p->context, linkedid, 0, "ALSA/%s", indevname)))
return NULL;
tmp->tech = &alsa_tech;
@@ -565,7 +565,7 @@ static struct ast_channel *alsa_new(struct chan_alsa_pvt *p, int state)
return tmp;
}
-static struct ast_channel *alsa_request(const char *type, int fmt, void *data, int *cause)
+static struct ast_channel *alsa_request(const char *type, int fmt, const struct ast_channel *requestor, void *data, int *cause)
{
int oldformat = fmt;
struct ast_channel *tmp = NULL;
@@ -580,7 +580,7 @@ static struct ast_channel *alsa_request(const char *type, int fmt, void *data, i
if (alsa.owner) {
ast_log(LOG_NOTICE, "Already have a call on the ALSA channel\n");
*cause = AST_CAUSE_BUSY;
- } else if (!(tmp = alsa_new(&alsa, AST_STATE_DOWN))) {
+ } else if (!(tmp = alsa_new(&alsa, AST_STATE_DOWN, requestor ? requestor->linkedid : NULL))) {
ast_log(LOG_WARNING, "Unable to create new ALSA channel\n");
}
@@ -833,7 +833,7 @@ static char *console_dial(struct ast_cli_entry *e, int cmd, struct ast_cli_args
ast_copy_string(alsa.exten, mye, sizeof(alsa.exten));
ast_copy_string(alsa.context, myc, sizeof(alsa.context));
hookstate = 1;
- alsa_new(&alsa, AST_STATE_RINGING);
+ alsa_new(&alsa, AST_STATE_RINGING, NULL);
} else
ast_cli(a->fd, "No such extension '%s' in context '%s'\n", mye, myc);
}
diff --git a/channels/chan_bridge.c b/channels/chan_bridge.c
index be41cd86c..be823cd32 100644
--- a/channels/chan_bridge.c
+++ b/channels/chan_bridge.c
@@ -46,7 +46,7 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
#include "asterisk/app.h"
#include "asterisk/bridging.h"
-static struct ast_channel *bridge_request(const char *type, int format, void *data, int *cause);
+static struct ast_channel *bridge_request(const char *type, int format, const struct ast_channel *requestor, void *data, int *cause);
static int bridge_call(struct ast_channel *ast, char *dest, int timeout);
static int bridge_hangup(struct ast_channel *ast);
static struct ast_frame *bridge_read(struct ast_channel *ast);
@@ -189,7 +189,7 @@ static int bridge_hangup(struct ast_channel *ast)
}
/*! \brief Called when we want to place a call somewhere, but not actually call it... yet */
-static struct ast_channel *bridge_request(const char *type, int format, void *data, int *cause)
+static struct ast_channel *bridge_request(const char *type, int format, const struct ast_channel *requestor, void *data, int *cause)
{
struct bridge_pvt *p = NULL;
@@ -199,11 +199,11 @@ static struct ast_channel *bridge_request(const char *type, int format, void *da
}
/* Try to grab two Asterisk channels to use as input and output channels */
- if (!(p->input = ast_channel_alloc(1, AST_STATE_UP, 0, 0, "", "", "", 0, "Bridge/%p-input", p))) {
+ if (!(p->input = ast_channel_alloc(1, AST_STATE_UP, 0, 0, "", "", "", requestor ? requestor->linkedid : NULL, 0, "Bridge/%p-input", p))) {
ast_free(p);
return NULL;
}
- if (!(p->output = ast_channel_alloc(1, AST_STATE_UP, 0, 0, "", "", "", 0, "Bridge/%p-output", p))) {
+ if (!(p->output = ast_channel_alloc(1, AST_STATE_UP, 0, 0, "", "", "", requestor ? requestor->linkedid : NULL, 0, "Bridge/%p-output", p))) {
p->input = ast_channel_release(p->input);
ast_free(p);
return NULL;
diff --git a/channels/chan_console.c b/channels/chan_console.c
index 091fcf1b1..55be76895 100644
--- a/channels/chan_console.c
+++ b/channels/chan_console.c
@@ -189,8 +189,8 @@ static struct ast_jb_conf default_jbconf = {
static struct ast_jb_conf global_jbconf;
/*! Channel Technology Callbacks @{ */
-static struct ast_channel *console_request(const char *type, int format,
- void *data, int *cause);
+static struct ast_channel *console_request(const char *type, int format,
+ const struct ast_channel *requestor, void *data, int *cause);
static int console_digit_begin(struct ast_channel *c, char digit);
static int console_digit_end(struct ast_channel *c, char digit, unsigned int duration);
static int console_text(struct ast_channel *c, const char *text);
@@ -413,12 +413,12 @@ static int stop_stream(struct console_pvt *pvt)
/*!
* \note Called with the pvt struct locked
*/
-static struct ast_channel *console_new(struct console_pvt *pvt, const char *ext, const char *ctx, int state)
+static struct ast_channel *console_new(struct console_pvt *pvt, const char *ext, const char *ctx, int state, const char *linkedid)
{
struct ast_channel *chan;
if (!(chan = ast_channel_alloc(1, state, pvt->cid_num, pvt->cid_name, NULL,
- ext, ctx, 0, "Console/%s", pvt->name))) {
+ ext, ctx, linkedid, 0, "Console/%s", pvt->name))) {
return NULL;
}
@@ -447,7 +447,7 @@ static struct ast_channel *console_new(struct console_pvt *pvt, const char *ext,
return chan;
}
-static struct ast_channel *console_request(const char *type, int format, void *data, int *cause)
+static struct ast_channel *console_request(const char *type, int format, const struct ast_channel *requestor, void *data, int *cause)
{
int oldformat = format;
struct ast_channel *chan = NULL;
@@ -471,7 +471,7 @@ static struct ast_channel *console_request(const char *type, int format, void *d
}
console_pvt_lock(pvt);
- chan = console_new(pvt, NULL, NULL, AST_STATE_DOWN);
+ chan = console_new(pvt, NULL, NULL, AST_STATE_DOWN, requestor ? requestor->linkedid : NULL);
console_pvt_unlock(pvt);
if (!chan)
@@ -833,7 +833,7 @@ static char *cli_console_dial(struct ast_cli_entry *e, int cmd, struct ast_cli_a
if (ast_exists_extension(NULL, myc, mye, 1, NULL)) {
console_pvt_lock(pvt);
pvt->hookstate = 1;
- console_new(pvt, mye, myc, AST_STATE_RINGING);
+ console_new(pvt, mye, myc, AST_STATE_RINGING, NULL);
console_pvt_unlock(pvt);
} else
ast_cli(a->fd, "No such extension '%s' in context '%s'\n", mye, myc);
diff --git a/channels/chan_dahdi.c b/channels/chan_dahdi.c
index e1c3348f4..a57e22169 100644
--- a/channels/chan_dahdi.c
+++ b/channels/chan_dahdi.c
@@ -1,7 +1,7 @@
/*
* Asterisk -- An open source telephony toolkit.
*
- * Copyright (C) 1999 - 2006, Digium, Inc.
+ * Copyright (C) 1999 - 2008, Digium, Inc.
*
* Mark Spencer <markster@digium.com>
*
@@ -91,6 +91,7 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
#include "asterisk/adsi.h"
#include "asterisk/cli.h"
#include "asterisk/cdr.h"
+#include "asterisk/cel.h"
#include "asterisk/features.h"
#include "asterisk/musiconhold.h"
#include "asterisk/say.h"
@@ -1388,7 +1389,7 @@ static struct dahdi_chan_conf dahdi_chan_conf_default(void)
}
-static struct ast_channel *dahdi_request(const char *type, int format, void *data, int *cause);
+static struct ast_channel *dahdi_request(const char *type, int format, const struct ast_channel *requestor, void *data, int *cause);
static int dahdi_digit_begin(struct ast_channel *ast, char digit);
static int dahdi_digit_end(struct ast_channel *ast, char digit, unsigned int duration);
static int dahdi_sendtext(struct ast_channel *c, const char *text);
@@ -1978,14 +1979,14 @@ static void my_swap_subchannels(void *pvt, enum analog_sub a, struct ast_channel
return;
}
-static struct ast_channel *dahdi_new(struct dahdi_pvt *, int, int, int, int, int);
+static struct ast_channel *dahdi_new(struct dahdi_pvt *, int, int, int, int, int, const char *);
-static struct ast_channel *my_new_analog_ast_channel(void *pvt, int state, int startpbx, enum analog_sub sub)
+static struct ast_channel *my_new_analog_ast_channel(void *pvt, int state, int startpbx, enum analog_sub sub, const struct ast_channel *requestor)
{
struct dahdi_pvt *p = pvt;
int dsub = analogsub_to_dahdisub(sub);
- return dahdi_new(p, state, startpbx, dsub, 0, 0);
+ return dahdi_new(p, state, startpbx, dsub, 0, 0, requestor ? requestor->linkedid : "");
}
#if defined(HAVE_PRI) || defined(HAVE_SS7)
@@ -2000,7 +2001,7 @@ static int dahdi_setlaw(int dfd, int law)
#endif
#ifdef HAVE_PRI
-static struct ast_channel *my_new_pri_ast_channel(void *pvt, int state, int startpbx, enum sig_pri_law law, int transfercapability, char *exten)
+static struct ast_channel *my_new_pri_ast_channel(void *pvt, int state, int startpbx, enum sig_pri_law law, int transfercapability, char *exten, const struct ast_channel *requestor)
{
struct dahdi_pvt *p = pvt;
int audio;
@@ -2028,7 +2029,7 @@ static struct ast_channel *my_new_pri_ast_channel(void *pvt, int state, int star
newlaw = DAHDI_LAW_MULAW;
break;
}
- return dahdi_new(p, state, startpbx, SUB_REAL, newlaw, transfercapability);
+ return dahdi_new(p, state, startpbx, SUB_REAL, newlaw, transfercapability, requestor ? requestor->linkedid : "");
}
#endif
@@ -2595,7 +2596,6 @@ static void dahdi_queue_frame(struct dahdi_pvt *p, struct ast_frame *f, void *da
#endif
}
-static struct ast_channel *dahdi_new(struct dahdi_pvt *, int, int, int, int, int);
#ifdef HAVE_OPENR2
static int dahdi_r2_answer(struct dahdi_pvt *p)
@@ -2764,7 +2764,7 @@ static void dahdi_r2_on_call_offered(openr2_chan_t *r2chan, const char *ani, con
}
if (!p->mfcr2_accept_on_offer) {
/* The user wants us to start the PBX thread right away without accepting the call first */
- c = dahdi_new(p, AST_STATE_RING, 1, SUB_REAL, DAHDI_LAW_ALAW, 0);
+ c = dahdi_new(p, AST_STATE_RING, 1, SUB_REAL, DAHDI_LAW_ALAW, 0, NULL);
if (c) {
dahdi_r2_update_monitor_count(p->mfcr2, 0);
/* Done here, don't disable reading now since we still need to generate MF tones to accept
@@ -2815,7 +2815,7 @@ static void dahdi_r2_on_call_accepted(openr2_chan_t *r2chan, openr2_call_mode_t
}
return;
}
- c = dahdi_new(p, AST_STATE_RING, 1, SUB_REAL, DAHDI_LAW_ALAW, 0);
+ c = dahdi_new(p, AST_STATE_RING, 1, SUB_REAL, DAHDI_LAW_ALAW, 0, NULL);
if (c) {
dahdi_r2_update_monitor_count(p->mfcr2, 0);
/* chan_dahdi will take care of reading from now on in the PBX thread, tell the
@@ -6747,7 +6747,7 @@ static struct ast_frame *dahdi_handle_event(struct ast_channel *ast)
goto winkflashdone;
}
/* Make new channel */
- chan = dahdi_new(p, AST_STATE_RESERVED, 0, SUB_THREEWAY, 0, 0);
+ chan = dahdi_new(p, AST_STATE_RESERVED, 0, SUB_THREEWAY, 0, 0, 0);
if (p->dahditrcallerid) {
if (!p->origcid_num)
p->origcid_num = ast_strdup(p->cid_num);
@@ -7102,6 +7102,12 @@ static struct ast_frame *__dahdi_exception(struct ast_channel *ast)
return f;
}
f = dahdi_handle_event(ast);
+
+ /* tell the cdr this zap device hung up */
+ if (f == NULL) {
+ ast_set_hangupsource(ast, ast->name, 0);
+ }
+
return f;
}
@@ -7722,7 +7728,7 @@ static int dahdi_indicate(struct ast_channel *chan, int condition, const void *d
return res;
}
-static struct ast_channel *dahdi_new(struct dahdi_pvt *i, int state, int startpbx, int idx, int law, int transfercapability)
+static struct ast_channel *dahdi_new(struct dahdi_pvt *i, int state, int startpbx, int idx, int law, int transfercapability, const char *linkedid)
{
struct ast_channel *tmp;
int deflaw;
@@ -7749,7 +7755,7 @@ static struct ast_channel *dahdi_new(struct dahdi_pvt *i, int state, int startpb
}
y++;
} while (x < 3);
- tmp = ast_channel_alloc(0, state, i->cid_num, i->cid_name, i->accountcode, i->exten, i->context, i->amaflags, "DAHDI/%s", ast_str_buffer(chan_name));
+ tmp = ast_channel_alloc(0, state, i->cid_num, i->cid_name, i->accountcode, i->exten, i->context, linkedid, i->amaflags, "DAHDI/%s", ast_str_buffer(chan_name));
if (!tmp)
return NULL;
tmp->tech = &dahdi_tech;
@@ -9158,7 +9164,7 @@ static void *mwi_thread(void *data)
restore_gains(mtd->pvt);
mtd->pvt->ringt = mtd->pvt->ringt_base;
- if ((chan = dahdi_new(mtd->pvt, AST_STATE_RING, 0, SUB_REAL, 0, 0))) {
+ if ((chan = dahdi_new(mtd->pvt, AST_STATE_RING, 0, SUB_REAL, 0, 0, NULL))) {
int result;
if (analog_lib_handles(mtd->pvt->sig, mtd->pvt->radio, mtd->pvt->oprmode)) {
result = analog_ss_thread_start(mtd->pvt->sig_pvt, chan);
@@ -9483,7 +9489,7 @@ static int handle_init_event(struct dahdi_pvt *i, int event)
dahdi_enable_ec(i);
/* The channel is immediately up. Start right away */
res = tone_zone_play_tone(i->subs[SUB_REAL].dfd, DAHDI_TONE_RINGTONE);
- chan = dahdi_new(i, AST_STATE_RING, 1, SUB_REAL, 0, 0);
+ chan = dahdi_new(i, AST_STATE_RING, 1, SUB_REAL, 0, 0, NULL);
if (!chan) {
ast_log(LOG_WARNING, "Unable to start PBX on channel %d\n", i->channel);
res = tone_zone_play_tone(i->subs[SUB_REAL].dfd, DAHDI_TONE_CONGESTION);
@@ -9492,7 +9498,7 @@ static int handle_init_event(struct dahdi_pvt *i, int event)
}
} else {
/* Check for callerid, digits, etc */
- chan = dahdi_new(i, AST_STATE_RESERVED, 0, SUB_REAL, 0, 0);
+ chan = dahdi_new(i, AST_STATE_RESERVED, 0, SUB_REAL, 0, 0, NULL);
if (chan) {
if (has_voicemail(i))
res = tone_zone_play_tone(i->subs[SUB_REAL].dfd, DAHDI_TONE_STUTTER);
@@ -9535,9 +9541,9 @@ static int handle_init_event(struct dahdi_pvt *i, int event)
case SIG_SF:
/* Check for callerid, digits, etc */
if (i->cid_start == CID_START_POLARITY_IN) {
- chan = dahdi_new(i, AST_STATE_PRERING, 0, SUB_REAL, 0, 0);
+ chan = dahdi_new(i, AST_STATE_PRERING, 0, SUB_REAL, 0, 0, NULL);
} else {
- chan = dahdi_new(i, AST_STATE_RING, 0, SUB_REAL, 0, 0);
+ chan = dahdi_new(i, AST_STATE_RING, 0, SUB_REAL, 0, 0, NULL);
}
if (!chan) {
@@ -9639,7 +9645,7 @@ static int handle_init_event(struct dahdi_pvt *i, int event)
ast_verb(2, "Starting post polarity "
"CID detection on channel %d\n",
i->channel);
- chan = dahdi_new(i, AST_STATE_PRERING, 0, SUB_REAL, 0, 0);
+ chan = dahdi_new(i, AST_STATE_PRERING, 0, SUB_REAL, 0, 0, NULL);
if (!chan) {
ast_log(LOG_WARNING, "Cannot allocate new structure on channel %d\n", i->channel);
} else if (ast_pthread_create_detached(&threadid, NULL, analog_ss_thread, chan)) {
@@ -10723,7 +10729,7 @@ static struct dahdi_pvt *mkintf(int channel, const struct dahdi_chan_conf *conf,
strsep(&context, "@");
if (ast_strlen_zero(context))
context = "default";
- tmp->mwi_event_sub = ast_event_subscribe(AST_EVENT_MWI, mwi_event_cb, NULL,
+ tmp->mwi_event_sub = ast_event_subscribe(AST_EVENT_MWI, mwi_event_cb, "Dahdi MWI subscription", NULL,
AST_EVENT_IE_MAILBOX, AST_EVENT_IE_PLTYPE_STR, mailbox,
AST_EVENT_IE_CONTEXT, AST_EVENT_IE_PLTYPE_STR, context,
AST_EVENT_IE_NEWMSGS, AST_EVENT_IE_PLTYPE_EXISTS,
@@ -11005,7 +11011,7 @@ static struct dahdi_pvt *duplicate_pseudo(struct dahdi_pvt *src)
return p;
}
-static struct ast_channel *dahdi_request(const char *type, int format, void *data, int *cause)
+static struct ast_channel *dahdi_request(const char *type, int format, const struct ast_channel *requestor, void *data, int *cause)
{
ast_group_t groupmatch = 0;
int channelmatch = -1;
@@ -11140,15 +11146,15 @@ static struct ast_channel *dahdi_request(const char *type, int format, void *dat
}
p->outgoing = 1;
if (analog_lib_handles(p->sig, p->radio, p->oprmode)) {
- tmp = analog_request(p->sig_pvt, &callwait);
- }
+ tmp = analog_request(p->sig_pvt, &callwait, requestor);
+ }
#ifdef HAVE_PRI
else if (p->sig == SIG_PRI || p->sig == SIG_BRI || p->sig == SIG_BRI_PTMP) {
- tmp = sig_pri_request(p->sig_pvt, SIG_PRI_DEFLAW);
+ tmp = sig_pri_request(p->sig_pvt, SIG_PRI_DEFLAW, requestor);
}
#endif
else {
- tmp = dahdi_new(p, AST_STATE_RESERVED, 0, p->owner ? SUB_CALLWAIT : SUB_REAL, 0, 0);
+ tmp = dahdi_new(p, AST_STATE_RESERVED, 0, p->owner ? SUB_CALLWAIT : SUB_REAL, 0, 0, requestor ? requestor->linkedid : "");
}
/* Make special notes */
@@ -11370,7 +11376,7 @@ static void ss7_start_call(struct dahdi_pvt *p, struct dahdi_ss7 *linkset)
}
ast_mutex_unlock(&linkset->lock);
- c = dahdi_new(p, AST_STATE_RING, 1, SUB_REAL, law, 0);
+ c = dahdi_new(p, AST_STATE_RING, 1, SUB_REAL, law, 0, NULL);
if (!c) {
ast_log(LOG_WARNING, "Unable to start PBX on CIC %d\n", p->cic);
diff --git a/channels/chan_gtalk.c b/channels/chan_gtalk.c
index bfa0915f6..6ad6ed904 100644
--- a/channels/chan_gtalk.c
+++ b/channels/chan_gtalk.c
@@ -166,7 +166,7 @@ static int global_capability = AST_FORMAT_ULAW | AST_FORMAT_ALAW | AST_FORMAT_GS
AST_MUTEX_DEFINE_STATIC(gtalklock); /*!< Protect the interface list (of gtalk_pvt's) */
/* Forward declarations */
-static struct ast_channel *gtalk_request(const char *type, int format, void *data, int *cause);
+static struct ast_channel *gtalk_request(const char *type, int format, const struct ast_channel *requestor, void *data, int *cause);
static int gtalk_digit(struct ast_channel *ast, char digit, unsigned int duration);
static int gtalk_digit_begin(struct ast_channel *ast, char digit);
static int gtalk_digit_end(struct ast_channel *ast, char digit, unsigned int duration);
@@ -986,7 +986,7 @@ static struct gtalk_pvt *gtalk_alloc(struct gtalk *client, const char *us, const
}
/*! \brief Start new gtalk channel */
-static struct ast_channel *gtalk_new(struct gtalk *client, struct gtalk_pvt *i, int state, const char *title)
+static struct ast_channel *gtalk_new(struct gtalk *client, struct gtalk_pvt *i, int state, const char *title, const char *linkedid)
{
struct ast_channel *tmp;
int fmt;
@@ -997,7 +997,7 @@ static struct ast_channel *gtalk_new(struct gtalk *client, struct gtalk_pvt *i,
n2 = title;
else
n2 = i->us;
- tmp = ast_channel_alloc(1, state, i->cid_num, i->cid_name, client->accountcode, i->exten, client->context, client->amaflags, "Gtalk/%s-%04lx", n2, ast_random() & 0xffff);
+ tmp = ast_channel_alloc(1, state, i->cid_num, i->cid_name, linkedid, client->accountcode, i->exten, client->context, client->amaflags, "Gtalk/%s-%04lx", n2, ast_random() & 0xffff);
if (!tmp) {
ast_log(LOG_WARNING, "Unable to allocate Gtalk channel structure!\n");
return NULL;
@@ -1191,7 +1191,7 @@ static int gtalk_newcall(struct gtalk *client, ikspak *pak)
return -1;
}
- chan = gtalk_new(client, p, AST_STATE_DOWN, pak->from->user);
+ chan = gtalk_new(client, p, AST_STATE_DOWN, pak->from->user, NULL);
if (!chan) {
gtalk_free_pvt(client, p);
return -1;
@@ -1634,7 +1634,7 @@ static int gtalk_hangup(struct ast_channel *ast)
}
/*! \brief Part of PBX interface */
-static struct ast_channel *gtalk_request(const char *type, int format, void *data, int *cause)
+static struct ast_channel *gtalk_request(const char *type, int format, const struct ast_channel *requestor, void *data, int *cause)
{
struct gtalk_pvt *p = NULL;
struct gtalk *client = NULL;
@@ -1673,7 +1673,7 @@ static struct ast_channel *gtalk_request(const char *type, int format, void *dat
ASTOBJ_WRLOCK(client);
p = gtalk_alloc(client, strchr(sender, '@') ? sender : client->connection->jid->full, strchr(to, '@') ? to : client->user, NULL);
if (p)
- chan = gtalk_new(client, p, AST_STATE_DOWN, to);
+ chan = gtalk_new(client, p, AST_STATE_DOWN, to, requestor ? requestor->linkedid : NULL);
ASTOBJ_UNLOCK(client);
return chan;
diff --git a/channels/chan_h323.c b/channels/chan_h323.c
index fd329538a..a4135a976 100644
--- a/channels/chan_h323.c
+++ b/channels/chan_h323.c
@@ -230,7 +230,7 @@ static void delete_users(void);
static void delete_aliases(void);
static void prune_peers(void);
-static struct ast_channel *oh323_request(const char *type, int format, void *data, int *cause);
+static struct ast_channel *oh323_request(const char *type, int format, const struct ast_channel *requestor, void *data, int *cause);
static int oh323_digit_begin(struct ast_channel *c, char digit);
static int oh323_digit_end(struct ast_channel *c, char digit, unsigned int duration);
static int oh323_call(struct ast_channel *c, char *dest, int timeout);
@@ -994,7 +994,7 @@ static int __oh323_rtp_create(struct oh323_pvt *pvt)
}
/*! \brief Private structure should be locked on a call */
-static struct ast_channel *__oh323_new(struct oh323_pvt *pvt, int state, const char *host)
+static struct ast_channel *__oh323_new(struct oh323_pvt *pvt, int state, const char *host, const char *linkedid)
{
struct ast_channel *ch;
char *cid_num, *cid_name;
@@ -1012,7 +1012,7 @@ static struct ast_channel *__oh323_new(struct oh323_pvt *pvt, int state, const c
/* Don't hold a oh323_pvt lock while we allocate a chanel */
ast_mutex_unlock(&pvt->lock);
- ch = ast_channel_alloc(1, state, cid_num, cid_name, pvt->accountcode, pvt->exten, pvt->context, pvt->amaflags, "H323/%s", host);
+ ch = ast_channel_alloc(1, state, cid_num, cid_name, pvt->accountcode, pvt->exten, pvt->context, linkedid, pvt->amaflags, "H323/%s", host);
/* Update usage counter */
ast_module_ref(ast_module_info->self);
ast_mutex_lock(&pvt->lock);
@@ -1717,7 +1717,7 @@ static int create_addr(struct oh323_pvt *pvt, char *opeer)
return 0;
}
}
-static struct ast_channel *oh323_request(const char *type, int format, void *data, int *cause)
+static struct ast_channel *oh323_request(const char *type, int format, const struct ast_channel *requestor, void *data, int *cause)
{
int oldformat;
struct oh323_pvt *pvt;
@@ -1793,7 +1793,7 @@ static struct ast_channel *oh323_request(const char *type, int format, void *dat
ast_mutex_unlock(&caplock);
ast_mutex_lock(&pvt->lock);
- tmpc = __oh323_new(pvt, AST_STATE_DOWN, tmp1);
+ tmpc = __oh323_new(pvt, AST_STATE_DOWN, tmp1, requestor ? requestor->linkedid : NULL);
ast_mutex_unlock(&pvt->lock);
if (!tmpc) {
oh323_destroy(pvt);
@@ -2277,7 +2277,7 @@ static int answer_call(unsigned call_reference, const char *token)
}
/* allocate a channel and tell asterisk about it */
- c = __oh323_new(pvt, AST_STATE_RINGING, pvt->cd.call_token);
+ c = __oh323_new(pvt, AST_STATE_RINGING, pvt->cd.call_token, NULL);
/* And release when done */
ast_mutex_unlock(&pvt->lock);
diff --git a/channels/chan_iax2.c b/channels/chan_iax2.c
index 89ec84335..3b6902e13 100644
--- a/channels/chan_iax2.c
+++ b/channels/chan_iax2.c
@@ -1104,7 +1104,7 @@ static int send_command_final(struct chan_iax2_pvt *, char, int, unsigned int, c
static int send_command_immediate(struct chan_iax2_pvt *, char, int, unsigned int, const unsigned char *, int, int);
static int send_command_locked(unsigned short callno, char, int, unsigned int, const unsigned char *, int, int);
static int send_command_transfer(struct chan_iax2_pvt *, char, int, unsigned int, const unsigned char *, int);
-static struct ast_channel *iax2_request(const char *type, int format, void *data, int *cause);
+static struct ast_channel *iax2_request(const char *type, int format, const struct ast_channel *requestor, void *data, int *cause);
static struct ast_frame *iax2_read(struct ast_channel *c);
static struct iax2_peer *build_peer(const char *name, struct ast_variable *v, struct ast_variable *alt, int temponly);
static struct iax2_user *build_user(const char *name, struct ast_variable *v, struct ast_variable *alt, int temponly);
@@ -4516,7 +4516,7 @@ static int iax2_getpeertrunk(struct sockaddr_in sin)
}
/*! \brief Create new call, interface with the PBX core */
-static struct ast_channel *ast_iax2_new(int callno, int state, int capability)
+static struct ast_channel *ast_iax2_new(int callno, int state, int capability, const char *linkedid)
{
struct ast_channel *tmp;
struct chan_iax2_pvt *i;
@@ -4529,7 +4529,7 @@ static struct ast_channel *ast_iax2_new(int callno, int state, int capability)
/* Don't hold call lock */
ast_mutex_unlock(&iaxsl[callno]);
- tmp = ast_channel_alloc(1, state, i->cid_num, i->cid_name, i->accountcode, i->exten, i->context, i->amaflags, "IAX2/%s-%d", i->host, i->callno);
+ tmp = ast_channel_alloc(1, state, i->cid_num, i->cid_name, i->accountcode, i->exten, i->context, linkedid, i->amaflags, "IAX2/%s-%d", i->host, i->callno);
ast_mutex_lock(&iaxsl[callno]);
if (i != iaxs[callno]) {
if (tmp) {
@@ -8003,8 +8003,8 @@ static int iax_park(struct ast_channel *chan1, struct ast_channel *chan2)
struct iax_dual *d;
struct ast_channel *chan1m, *chan2m;
pthread_t th;
- chan1m = ast_channel_alloc(0, AST_STATE_DOWN, 0, 0, chan2->accountcode, chan1->exten, chan1->context, chan1->amaflags, "Parking/%s", chan1->name);
- chan2m = ast_channel_alloc(0, AST_STATE_DOWN, 0, 0, chan2->accountcode, chan2->exten, chan2->context, chan2->amaflags, "IAXPeer/%s",chan2->name);
+ chan1m = ast_channel_alloc(0, AST_STATE_DOWN, 0, 0, chan2->accountcode, chan1->exten, chan1->context, chan1->linkedid, chan1->amaflags, "Parking/%s", chan1->name);
+ chan2m = ast_channel_alloc(0, AST_STATE_DOWN, 0, 0, chan2->accountcode, chan2->exten, chan2->context, chan2->linkedid, chan2->amaflags, "IAXPeer/%s", chan2->name);
if (chan2m && chan1m) {
/* Make formats okay */
chan1m->readformat = chan1->readformat;
@@ -8512,6 +8512,35 @@ static struct ast_custom_function iaxvar_function = {
.write = acf_iaxvar_write,
};
+static void set_hangup_source_and_cause(int callno, unsigned char causecode)
+{
+ int locked = 0;
+ struct ast_channel *owner=NULL;
+
+ do {
+ if (ast_channel_trylock(iaxs[callno]->owner)) {
+ DEADLOCK_AVOIDANCE(&iaxsl[callno]);
+ }
+ else {
+ locked = 1;
+ owner = iaxs[callno]->owner;
+ }
+ }
+ while (!locked && iaxs[callno] && iaxs[callno]->owner);
+
+ if (iaxs[callno] && iaxs[callno]->owner) {
+ if (causecode) {
+ iaxs[callno]->owner->hangupcause = causecode;
+ }
+ ast_set_hangupsource(iaxs[callno]->owner, iaxs[callno]->owner->name, 0);
+ ast_channel_unlock(owner);
+ }
+ if (locked) {
+ ast_channel_unlock(owner);
+ }
+}
+
+
static int socket_process(struct iax2_thread *thread)
{
struct sockaddr_in sin;
@@ -8853,7 +8882,7 @@ static int socket_process(struct iax2_thread *thread)
(f.frametype == AST_FRAME_IAX)) {
if (ast_test_flag64(iaxs[fr->callno], IAX_DELAYPBXSTART)) {
ast_clear_flag64(iaxs[fr->callno], IAX_DELAYPBXSTART);
- if (!ast_iax2_new(fr->callno, AST_STATE_RING, iaxs[fr->callno]->chosenformat)) {
+ if (!ast_iax2_new(fr->callno, AST_STATE_RING, iaxs[fr->callno]->chosenformat, NULL)) {
ast_mutex_unlock(&iaxsl[fr->callno]);
return 1;
}
@@ -9276,17 +9305,28 @@ retryowner:
case IAX_COMMAND_HANGUP:
ast_set_flag64(iaxs[fr->callno], IAX_ALREADYGONE);
ast_debug(1, "Immediately destroying %d, having received hangup\n", fr->callno);
- /* Set hangup cause according to remote */
- if (ies.causecode && iaxs[fr->callno]->owner)
- iaxs[fr->callno]->owner->hangupcause = ies.causecode;
+ /* Set hangup cause according to remote and hangupsource */
+ if (iaxs[fr->callno]->owner) {
+ set_hangup_source_and_cause(fr->callno, ies.causecode);
+ if (!iaxs[fr->callno]) {
+ ast_mutex_unlock(&iaxsl[fr->callno]);
+ return 1;
+ }
+ }
+
/* Send ack immediately, before we destroy */
send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
iax2_destroy(fr->callno);
break;
case IAX_COMMAND_REJECT:
- /* Set hangup cause according to remote */
- if (ies.causecode && iaxs[fr->callno]->owner)
- iaxs[fr->callno]->owner->hangupcause = ies.causecode;
+ /* Set hangup cause according to remote and hangup source */
+ if (iaxs[fr->callno]->owner) {
+ set_hangup_source_and_cause(fr->callno, ies.causecode);
+ if (!iaxs[fr->callno]) {
+ ast_mutex_unlock(&iaxsl[fr->callno]);
+ return 1;
+ }
+ }
if (!ast_test_flag64(iaxs[fr->callno], IAX_PROVISION)) {
if (iaxs[fr->callno]->owner && authdebug)
@@ -9668,7 +9708,7 @@ retryowner2:
using_prefs);
ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED);
- if (!(c = ast_iax2_new(fr->callno, AST_STATE_RING, format)))
+ if (!(c = ast_iax2_new(fr->callno, AST_STATE_RING, format, NULL)))
iax2_destroy(fr->callno);
else if (ies.vars) {
struct ast_datastore *variablestore;
@@ -9737,7 +9777,7 @@ immediatedial:
ast_verb(3, "Accepting DIAL from %s, formats = 0x%x\n", ast_inet_ntoa(sin.sin_addr), iaxs[fr->callno]->peerformat);
ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED);
send_command(iaxs[fr->callno], AST_FRAME_CONTROL, AST_CONTROL_PROGRESS, 0, NULL, 0, -1);
- if (!(c = ast_iax2_new(fr->callno, AST_STATE_RING, iaxs[fr->callno]->peerformat)))
+ if (!(c = ast_iax2_new(fr->callno, AST_STATE_RING, iaxs[fr->callno]->peerformat, NULL)))
iax2_destroy(fr->callno);
else if (ies.vars) {
struct ast_datastore *variablestore;
@@ -10570,7 +10610,7 @@ static void free_context(struct iax2_context *con)
}
}
-static struct ast_channel *iax2_request(const char *type, int format, void *data, int *cause)
+static struct ast_channel *iax2_request(const char *type, int format, const struct ast_channel *requestor, void *data, int *cause)
{
int callno;
int res;
@@ -10622,7 +10662,7 @@ static struct ast_channel *iax2_request(const char *type, int format, void *data
if (cai.found)
ast_string_field_set(iaxs[callno], host, pds.peer);
- c = ast_iax2_new(callno, AST_STATE_DOWN, cai.capability);
+ c = ast_iax2_new(callno, AST_STATE_DOWN, cai.capability, requestor ? requestor->linkedid : NULL);
ast_mutex_unlock(&iaxsl[callno]);
@@ -11086,7 +11126,7 @@ static struct iax2_peer *build_peer(const char *name, struct ast_variable *v, st
strsep(&context, "@");
if (ast_strlen_zero(context))
context = "default";
- peer->mwi_event_sub = ast_event_subscribe(AST_EVENT_MWI, mwi_event_cb, NULL,
+ peer->mwi_event_sub = ast_event_subscribe(AST_EVENT_MWI, mwi_event_cb, "IAX MWI subscription", NULL,
AST_EVENT_IE_MAILBOX, AST_EVENT_IE_PLTYPE_STR, mailbox,
AST_EVENT_IE_CONTEXT, AST_EVENT_IE_PLTYPE_STR, context,
AST_EVENT_IE_END);
diff --git a/channels/chan_jingle.c b/channels/chan_jingle.c
index 01909f1f8..da98986eb 100644
--- a/channels/chan_jingle.c
+++ b/channels/chan_jingle.c
@@ -168,7 +168,7 @@ static int global_capability = AST_FORMAT_ULAW | AST_FORMAT_ALAW | AST_FORMAT_GS
AST_MUTEX_DEFINE_STATIC(jinglelock); /*!< Protect the interface list (of jingle_pvt's) */
/* Forward declarations */
-static struct ast_channel *jingle_request(const char *type, int format, void *data, int *cause);
+static struct ast_channel *jingle_request(const char *type, int format, const struct ast_channel *requestor, void *data, int *cause);
static int jingle_digit_begin(struct ast_channel *ast, char digit);
static int jingle_digit_end(struct ast_channel *ast, char digit, unsigned int duration);
static int jingle_call(struct ast_channel *ast, char *dest, int timeout);
@@ -789,7 +789,7 @@ static struct jingle_pvt *jingle_alloc(struct jingle *client, const char *from,
}
/*! \brief Start new jingle channel */
-static struct ast_channel *jingle_new(struct jingle *client, struct jingle_pvt *i, int state, const char *title)
+static struct ast_channel *jingle_new(struct jingle *client, struct jingle_pvt *i, int state, const char *title, const char *linkedid)
{
struct ast_channel *tmp;
int fmt;
@@ -800,7 +800,7 @@ static struct ast_channel *jingle_new(struct jingle *client, struct jingle_pvt *
str = title;
else
str = i->them;
- tmp = ast_channel_alloc(1, state, i->cid_num, i->cid_name, "", "", "", 0, "Jingle/%s-%04lx", str, ast_random() & 0xffff);
+ tmp = ast_channel_alloc(1, state, i->cid_num, i->cid_name, "", "", "", linkedid, 0, "Jingle/%s-%04lx", str, ast_random() & 0xffff);
if (!tmp) {
ast_log(LOG_WARNING, "Unable to allocate Jingle channel structure!\n");
return NULL;
@@ -980,7 +980,7 @@ static int jingle_newcall(struct jingle *client, ikspak *pak)
ast_log(LOG_WARNING, "Unable to allocate jingle structure!\n");
return -1;
}
- chan = jingle_new(client, p, AST_STATE_DOWN, pak->from->user);
+ chan = jingle_new(client, p, AST_STATE_DOWN, pak->from->user, NULL);
if (!chan) {
jingle_free_pvt(client, p);
return -1;
@@ -1457,7 +1457,7 @@ static int jingle_hangup(struct ast_channel *ast)
}
/*! \brief Part of PBX interface */
-static struct ast_channel *jingle_request(const char *request_type, int format, void *data, int *cause)
+static struct ast_channel *jingle_request(const char *type, int format, const struct ast_channel *requestor, void *data, int *cause)
{
struct jingle_pvt *p = NULL;
struct jingle *client = NULL;
@@ -1495,7 +1495,7 @@ static struct ast_channel *jingle_request(const char *request_type, int format,
ASTOBJ_WRLOCK(client);
p = jingle_alloc(client, to, NULL);
if (p)
- chan = jingle_new(client, p, AST_STATE_DOWN, to);
+ chan = jingle_new(client, p, AST_STATE_DOWN, to, requestor ? requestor->linkedid : NULL);
ASTOBJ_UNLOCK(client);
return chan;
diff --git a/channels/chan_local.c b/channels/chan_local.c
index 329b9828e..df1a2c454 100644
--- a/channels/chan_local.c
+++ b/channels/chan_local.c
@@ -60,7 +60,7 @@ static struct ast_jb_conf g_jb_conf = {
.impl = "",
};
-static struct ast_channel *local_request(const char *type, int format, void *data, int *cause);
+static struct ast_channel *local_request(const char *type, int format, const struct ast_channel *requestor, void *data, int *cause);
static int local_digit_begin(struct ast_channel *ast, char digit);
static int local_digit_end(struct ast_channel *ast, char digit, unsigned int duration);
static int local_call(struct ast_channel *ast, char *dest, int timeout);
@@ -780,7 +780,7 @@ static struct local_pvt *local_alloc(const char *data, int format)
}
/*! \brief Start new local channel */
-static struct ast_channel *local_new(struct local_pvt *p, int state)
+static struct ast_channel *local_new(struct local_pvt *p, int state, const char *linkedid)
{
struct ast_channel *tmp = NULL, *tmp2 = NULL;
int randnum = ast_random() & 0xffff, fmt = 0;
@@ -798,8 +798,8 @@ static struct ast_channel *local_new(struct local_pvt *p, int state)
ama = p->owner->amaflags;
else
ama = 0;
- if (!(tmp = ast_channel_alloc(1, state, 0, 0, t, p->exten, p->context, ama, "Local/%s@%s-%04x;1", p->exten, p->context, randnum))
- || !(tmp2 = ast_channel_alloc(1, AST_STATE_RING, 0, 0, t, p->exten, p->context, ama, "Local/%s@%s-%04x;2", p->exten, p->context, randnum))) {
+ if (!(tmp = ast_channel_alloc(1, state, 0, 0, t, p->exten, p->context, linkedid, ama, "Local/%s@%s-%04x;1", p->exten, p->context, randnum))
+ || !(tmp2 = ast_channel_alloc(1, AST_STATE_RING, 0, 0, t, p->exten, p->context, linkedid, ama, "Local/%s@%s-%04x;2", p->exten, p->context, randnum))) {
if (tmp) {
tmp = ast_channel_release(tmp);
}
@@ -843,14 +843,14 @@ static struct ast_channel *local_new(struct local_pvt *p, int state)
}
/*! \brief Part of PBX interface */
-static struct ast_channel *local_request(const char *type, int format, void *data, int *cause)
+static struct ast_channel *local_request(const char *type, int format, const struct ast_channel *requestor, void *data, int *cause)
{
struct local_pvt *p = NULL;
struct ast_channel *chan = NULL;
/* Allocate a new private structure and then Asterisk channel */
if ((p = local_alloc(data, format))) {
- if (!(chan = local_new(p, AST_STATE_DOWN))) {
+ if (!(chan = local_new(p, AST_STATE_DOWN, requestor ? requestor->linkedid : NULL))) {
AST_LIST_LOCK(&locals);
AST_LIST_REMOVE(&locals, p, list);
AST_LIST_UNLOCK(&locals);
diff --git a/channels/chan_mgcp.c b/channels/chan_mgcp.c
index be38e87b6..d682c76bb 100644
--- a/channels/chan_mgcp.c
+++ b/channels/chan_mgcp.c
@@ -418,7 +418,7 @@ static void dump_cmd_queues(struct mgcp_endpoint *p, struct mgcp_subchannel *sub
static char *mgcp_reload(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a);
static int reload_config(int reload);
-static struct ast_channel *mgcp_request(const char *type, int format, void *data, int *cause);
+static struct ast_channel *mgcp_request(const char *type, int format, const struct ast_channel *requestor, void *data, int *cause);
static int mgcp_call(struct ast_channel *ast, char *dest, int timeout);
static int mgcp_hangup(struct ast_channel *ast);
static int mgcp_answer(struct ast_channel *ast);
@@ -1466,13 +1466,13 @@ static int mgcp_indicate(struct ast_channel *ast, int ind, const void *data, siz
return res;
}
-static struct ast_channel *mgcp_new(struct mgcp_subchannel *sub, int state)
+static struct ast_channel *mgcp_new(struct mgcp_subchannel *sub, int state, const char *linkedid)
{
struct ast_channel *tmp;
struct mgcp_endpoint *i = sub->parent;
int fmt;
- tmp = ast_channel_alloc(1, state, i->cid_num, i->cid_name, i->accountcode, i->exten, i->context, i->amaflags, "MGCP/%s@%s-%d", i->name, i->parent->name, sub->id);
+ tmp = ast_channel_alloc(1, state, i->cid_num, i->cid_name, linkedid, i->accountcode, i->exten, i->context, i->amaflags, "MGCP/%s@%s-%d", i->name, i->parent->name, sub->id);
if (tmp) {
tmp->tech = &mgcp_tech;
tmp->nativeformats = i->capability;
@@ -2967,7 +2967,7 @@ static void handle_hd_hf(struct mgcp_subchannel *sub, char *ev)
#else
transmit_notify_request(sub, "G/rt");
#endif
- c = mgcp_new(sub, AST_STATE_RING);
+ c = mgcp_new(sub, AST_STATE_RING, NULL);
if (!c) {
ast_log(LOG_WARNING, "Unable to start PBX on channel %s@%s\n", p->name, p->parent->name);
transmit_notify_request(sub, "G/cg");
@@ -2979,7 +2979,7 @@ static void handle_hd_hf(struct mgcp_subchannel *sub, char *ev)
} else {
transmit_notify_request(sub, "L/dl");
}
- c = mgcp_new(sub, AST_STATE_DOWN);
+ c = mgcp_new(sub, AST_STATE_DOWN, NULL);
if (c) {
if (ast_pthread_create_detached(&t, NULL, mgcp_ss, c)) {
ast_log(LOG_WARNING, "Unable to create switch thread: %s\n", strerror(errno));
@@ -3489,7 +3489,7 @@ static int restart_monitor(void)
return 0;
}
-static struct ast_channel *mgcp_request(const char *type, int format, void *data, int *cause)
+static struct ast_channel *mgcp_request(const char *type, int format, const struct ast_channel *requestor, void *data, int *cause)
{
int oldformat;
struct mgcp_subchannel *sub;
@@ -3533,7 +3533,7 @@ static struct ast_channel *mgcp_request(const char *type, int format, void *data
ast_mutex_unlock(&sub->lock);
return NULL;
}
- tmpc = mgcp_new(sub->owner ? sub->next : sub, AST_STATE_DOWN);
+ tmpc = mgcp_new(sub->owner ? sub->next : sub, AST_STATE_DOWN, requestor ? requestor->linkedid : NULL);
ast_mutex_unlock(&sub->lock);
if (!tmpc)
ast_log(LOG_WARNING, "Unable to make channel for '%s'\n", tmp);
@@ -3726,7 +3726,7 @@ static struct mgcp_gateway *build_gateway(char *cat, struct ast_variable *v)
strsep(&cntx, "@");
if (ast_strlen_zero(cntx))
cntx = "default";
- e->mwi_event_sub = ast_event_subscribe(AST_EVENT_MWI, mwi_event_cb, NULL,
+ e->mwi_event_sub = ast_event_subscribe(AST_EVENT_MWI, mwi_event_cb, "MGCP MWI subscription", NULL,
AST_EVENT_IE_MAILBOX, AST_EVENT_IE_PLTYPE_STR, mbox,
AST_EVENT_IE_CONTEXT, AST_EVENT_IE_PLTYPE_STR, cntx,
AST_EVENT_IE_NEWMSGS, AST_EVENT_IE_PLTYPE_EXISTS,
diff --git a/channels/chan_misdn.c b/channels/chan_misdn.c
index 44e096d3d..3a11f74f1 100644
--- a/channels/chan_misdn.c
+++ b/channels/chan_misdn.c
@@ -657,7 +657,7 @@ static int *misdn_ports;
static void chan_misdn_log(int level, int port, char *tmpl, ...)
__attribute__((format(printf, 3, 4)));
-static struct ast_channel *misdn_new(struct chan_list *cl, int state, char *exten, char *callerid, int format, int port, int c);
+static struct ast_channel *misdn_new(struct chan_list *cl, int state, char *exten, char *callerid, int format, const char *linkedid, int port, int c);
static void send_digit_to_chan(struct chan_list *cl, char digit);
static void hangup_chan(struct chan_list *ch);
@@ -7468,7 +7468,7 @@ static struct chan_list *init_chan_list(int orig)
return cl;
}
-static struct ast_channel *misdn_request(const char *type, int format, void *data, int *cause)
+static struct ast_channel *misdn_request(const char *type, int format, const struct ast_channel *requestor, void *data, int *cause)
{
struct ast_channel *ast;
char group[BUFFERSIZE + 1] = "";
@@ -7694,7 +7694,7 @@ static struct ast_channel *misdn_request(const char *type, int format, void *dat
}
cl->bc = newbc;
- ast = misdn_new(cl, AST_STATE_RESERVED, args.ext, NULL, format, port, channel);
+ ast = misdn_new(cl, AST_STATE_RESERVED, args.ext, NULL, format, requestor ? requestor->linkedid : NULL, port, channel);
if (!ast) {
ast_log(LOG_ERROR, "Could not create Asterisk channel for Dial(%s)\n", dial_str);
return NULL;
@@ -7799,7 +7799,7 @@ static void update_name(struct ast_channel *tmp, int port, int c)
}
}
-static struct ast_channel *misdn_new(struct chan_list *chlist, int state, char *exten, char *callerid, int format, int port, int c)
+static struct ast_channel *misdn_new(struct chan_list *chlist, int state, char *exten, char *callerid, int format, const char *linkedid, int port, int c)
{
struct ast_channel *tmp;
char *cid_name = 0, *cid_num = 0;
@@ -7821,7 +7821,7 @@ static struct ast_channel *misdn_new(struct chan_list *chlist, int state, char
ast_callerid_parse(callerid, &cid_name, &cid_num);
}
- tmp = ast_channel_alloc(1, state, cid_num, cid_name, "", exten, "", 0, "%s/%s%d-u%d", misdn_type, c ? "" : "tmp", chan_offset + c, glob_channel++);
+ tmp = ast_channel_alloc(1, state, cid_num, cid_name, "", exten, "", linkedid, 0, "%s/%s%d-u%d", misdn_type, c ? "" : "tmp", chan_offset + c, glob_channel++);
if (tmp) {
chan_misdn_log(2, 0, " --> * NEW CHANNEL dialed:%s caller:%s\n", exten, callerid);
@@ -8436,7 +8436,7 @@ static void misdn_cc_pbx_notify(long record_id, const struct misdn_cc_notify *no
/* Create a channel to notify with */
snprintf(id_str, sizeof(id_str), "%ld", record_id);
chan = ast_channel_alloc(0, AST_STATE_DOWN, id_str, NULL, NULL,
- notify->exten, notify->context, 0,
+ notify->exten, notify->context, NULL, 0,
"mISDN-CC/%ld-%X", record_id, (unsigned) ++sequence);
if (!chan) {
ast_log(LOG_ERROR, "Unable to allocate channel!\n");
@@ -9581,7 +9581,7 @@ cb_events(enum event_e event, struct misdn_bchannel *bc, void *user_data)
ch->l3id = bc->l3_id;
ch->addr = bc->addr;
- chan = misdn_new(ch, AST_STATE_RESERVED, bc->dialed.number, bc->caller.number, AST_FORMAT_ALAW, bc->port, bc->channel);
+ chan = misdn_new(ch, AST_STATE_RESERVED, bc->dialed.number, bc->caller.number, AST_FORMAT_ALAW, NULL, bc->port, bc->channel);
if (!chan) {
misdn_lib_send_event(bc,EVENT_RELEASE_COMPLETE);
ast_log(LOG_ERROR, "cb_events: misdn_new failed !\n");
diff --git a/channels/chan_multicast_rtp.c b/channels/chan_multicast_rtp.c
index 589fa1008..d2bbc6875 100644
--- a/channels/chan_multicast_rtp.c
+++ b/channels/chan_multicast_rtp.c
@@ -52,7 +52,7 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
static const char tdesc[] = "Multicast RTP Paging Channel Driver";
/* Forward declarations */
-static struct ast_channel *multicast_rtp_request(const char *type, int format, void *data, int *cause);
+static struct ast_channel *multicast_rtp_request(const char *type, int format, const struct ast_channel *requestor, void *data, int *cause);
static int multicast_rtp_call(struct ast_channel *ast, char *dest, int timeout);
static int multicast_rtp_hangup(struct ast_channel *ast);
static struct ast_frame *multicast_rtp_read(struct ast_channel *ast);
@@ -107,7 +107,7 @@ static int multicast_rtp_hangup(struct ast_channel *ast)
}
/*! \brief Function called when we should prepare to call the destination */
-static struct ast_channel *multicast_rtp_request(const char *type, int format, void *data, int *cause)
+static struct ast_channel *multicast_rtp_request(const char *type, int format, const struct ast_channel *requestor, void *data, int *cause)
{
char *tmp = ast_strdupa(data), *multicast_type = tmp, *destination, *control;
struct ast_rtp_instance *instance;
@@ -140,7 +140,7 @@ static struct ast_channel *multicast_rtp_request(const char *type, int format, v
goto failure;
}
- if (!(chan = ast_channel_alloc(1, AST_STATE_DOWN, "", "", "", "", "", 0, "MulticastRTP/%p", instance))) {
+ if (!(chan = ast_channel_alloc(1, AST_STATE_DOWN, "", "", "", "", "", requestor ? requestor->linkedid : "", 0, "MulticastRTP/%p", instance))) {
ast_rtp_instance_destroy(instance);
goto failure;
}
diff --git a/channels/chan_nbs.c b/channels/chan_nbs.c
index 8729f1074..89c5f647c 100644
--- a/channels/chan_nbs.c
+++ b/channels/chan_nbs.c
@@ -66,7 +66,7 @@ struct nbs_pvt {
struct ast_module_user *u; /*! for holding a reference to this module */
};
-static struct ast_channel *nbs_request(const char *type, int format, void *data, int *cause);
+static struct ast_channel *nbs_request(const char *type, int format, const struct ast_channel *requestor, void *data, int *cause);
static int nbs_call(struct ast_channel *ast, char *dest, int timeout);
static int nbs_hangup(struct ast_channel *ast);
static struct ast_frame *nbs_xread(struct ast_channel *ast);
@@ -219,10 +219,10 @@ static int nbs_xwrite(struct ast_channel *ast, struct ast_frame *frame)
return 0;
}
-static struct ast_channel *nbs_new(struct nbs_pvt *i, int state)
+static struct ast_channel *nbs_new(struct nbs_pvt *i, int state, const char *linkedid)
{
struct ast_channel *tmp;
- tmp = ast_channel_alloc(1, state, 0, 0, "", "s", context, 0, "NBS/%s", i->stream);
+ tmp = ast_channel_alloc(1, state, 0, 0, "", "s", context, linkedid, 0, "NBS/%s", i->stream);
if (tmp) {
tmp->tech = &nbs_tech;
ast_channel_set_fd(tmp, 0, nbs_fd(i->nbs));
@@ -251,7 +251,7 @@ static struct ast_channel *nbs_new(struct nbs_pvt *i, int state)
}
-static struct ast_channel *nbs_request(const char *type, int format, void *data, int *cause)
+static struct ast_channel *nbs_request(const char *type, int format, const struct ast_channel *requestor, void *data, int *cause)
{
int oldformat;
struct nbs_pvt *p;
@@ -265,7 +265,7 @@ static struct ast_channel *nbs_request(const char *type, int format, void *data,
}
p = nbs_alloc(data);
if (p) {
- tmp = nbs_new(p, AST_STATE_DOWN);
+ tmp = nbs_new(p, AST_STATE_DOWN, requestor ? requestor->linkedid : NULL);
if (!tmp)
nbs_destroy(p);
}
diff --git a/channels/chan_oss.c b/channels/chan_oss.c
index b3ff44883..9b2201a48 100644
--- a/channels/chan_oss.c
+++ b/channels/chan_oss.c
@@ -332,7 +332,8 @@ static struct chan_oss_pvt oss_default = {
static int setformat(struct chan_oss_pvt *o, int mode);
-static struct ast_channel *oss_request(const char *type, int format, void *data, int *cause);
+static struct ast_channel *oss_request(const char *type, int format, const struct ast_channel *requestor,
+ void *data, int *cause);
static int oss_digit_begin(struct ast_channel *c, char digit);
static int oss_digit_end(struct ast_channel *c, char digit, unsigned int duration);
static int oss_text(struct ast_channel *c, const char *text);
@@ -787,11 +788,11 @@ static int oss_indicate(struct ast_channel *c, int cond, const void *data, size_
/*!
* \brief allocate a new channel.
*/
-static struct ast_channel *oss_new(struct chan_oss_pvt *o, char *ext, char *ctx, int state)
+static struct ast_channel *oss_new(struct chan_oss_pvt *o, char *ext, char *ctx, int state, const char *linkedid)
{
struct ast_channel *c;
- c = ast_channel_alloc(1, state, o->cid_num, o->cid_name, "", ext, ctx, 0, "Console/%s", o->device + 5);
+ c = ast_channel_alloc(1, state, o->cid_num, o->cid_name, "", ext, ctx, linkedid, 0, "Console/%s", o->device + 5);
if (c == NULL)
return NULL;
c->tech = &oss_tech;
@@ -830,7 +831,7 @@ static struct ast_channel *oss_new(struct chan_oss_pvt *o, char *ext, char *ctx,
return c;
}
-static struct ast_channel *oss_request(const char *type, int format, void *data, int *cause)
+static struct ast_channel *oss_request(const char *type, int format, const struct ast_channel *requestor, void *data, int *cause)
{
struct ast_channel *c;
struct chan_oss_pvt *o;
@@ -858,7 +859,7 @@ static struct ast_channel *oss_request(const char *type, int format, void *data,
*cause = AST_CAUSE_BUSY;
return NULL;
}
- c = oss_new(o, NULL, NULL, AST_STATE_DOWN);
+ c = oss_new(o, NULL, NULL, AST_STATE_DOWN, requestor ? requestor->linkedid : NULL);
if (c == NULL) {
ast_log(LOG_WARNING, "Unable to create new OSS channel\n");
return NULL;
@@ -1117,7 +1118,7 @@ static char *console_dial(struct ast_cli_entry *e, int cmd, struct ast_cli_args
myc = o->ctx;
if (ast_exists_extension(NULL, myc, mye, 1, NULL)) {
o->hookstate = 1;
- oss_new(o, mye, myc, AST_STATE_RINGING);
+ oss_new(o, mye, myc, AST_STATE_RINGING, NULL);
} else
ast_cli(a->fd, "No such extension '%s' in context '%s'\n", mye, myc);
if (s)
diff --git a/channels/chan_phone.c b/channels/chan_phone.c
index dd1578cb8..d3131210c 100644
--- a/channels/chan_phone.c
+++ b/channels/chan_phone.c
@@ -150,7 +150,7 @@ static struct phone_pvt {
static char cid_num[AST_MAX_EXTENSION];
static char cid_name[AST_MAX_EXTENSION];
-static struct ast_channel *phone_request(const char *type, int format, void *data, int *cause);
+static struct ast_channel *phone_request(const char *type, int format, const struct ast_channel *requestor, void *data, int *cause);
static int phone_digit_begin(struct ast_channel *ast, char digit);
static int phone_digit_end(struct ast_channel *ast, char digit, unsigned int duration);
static int phone_call(struct ast_channel *ast, char *dest, int timeout);
@@ -844,11 +844,11 @@ static int phone_write(struct ast_channel *ast, struct ast_frame *frame)
return 0;
}
-static struct ast_channel *phone_new(struct phone_pvt *i, int state, char *cntx)
+static struct ast_channel *phone_new(struct phone_pvt *i, int state, char *cntx, const char *linkedid)
{
struct ast_channel *tmp;
struct phone_codec_data queried_codec;
- tmp = ast_channel_alloc(1, state, i->cid_num, i->cid_name, "", i->ext, i->context, 0, "Phone/%s", i->dev + 5);
+ tmp = ast_channel_alloc(1, state, i->cid_num, i->cid_name, "", i->ext, i->context, linkedid, 0, "Phone/%s", i->dev + 5);
if (tmp) {
tmp->tech = cur_tech;
ast_channel_set_fd(tmp, 0, i->fd);
@@ -941,14 +941,14 @@ static void phone_check_exception(struct phone_pvt *i)
!phonee.bits.dtmf_ready) &&
ast_exists_extension(NULL, i->context, i->ext, 1, i->cid_num)) {
/* It's a valid extension in its context, get moving! */
- phone_new(i, AST_STATE_RING, i->context);
+ phone_new(i, AST_STATE_RING, i->context, NULL);
/* No need to restart monitor, we are the monitor */
} else if (!ast_canmatch_extension(NULL, i->context, i->ext, 1, i->cid_num)) {
/* There is nothing in the specified extension that can match anymore.
Try the default */
if (ast_exists_extension(NULL, "default", i->ext, 1, i->cid_num)) {
/* Check the default, too... */
- phone_new(i, AST_STATE_RING, "default");
+ phone_new(i, AST_STATE_RING, "default", NULL);
/* XXX This should probably be justified better XXX */
} else if (!ast_canmatch_extension(NULL, "default", i->ext, 1, i->cid_num)) {
/* It's not a valid extension, give a busy signal */
@@ -966,7 +966,7 @@ static void phone_check_exception(struct phone_pvt *i)
offhook = ioctl(i->fd, PHONE_HOOKSTATE);
if (offhook) {
if (i->mode == MODE_IMMEDIATE) {
- phone_new(i, AST_STATE_RING, i->context);
+ phone_new(i, AST_STATE_RING, i->context, NULL);
} else if (i->mode == MODE_DIALTONE) {
ast_module_ref(ast_module_info->self);
/* Reset the extension */
@@ -1002,7 +1002,7 @@ static void phone_check_exception(struct phone_pvt *i)
}
if (phonee.bits.pstn_ring) {
ast_verbose("Unit is ringing\n");
- phone_new(i, AST_STATE_RING, i->context);
+ phone_new(i, AST_STATE_RING, i->context, NULL);
}
if (phonee.bits.caller_id)
ast_verbose("We have caller ID\n");
@@ -1212,7 +1212,7 @@ static struct phone_pvt *mkif(const char *iface, int mode, int txgain, int rxgai
return tmp;
}
-static struct ast_channel *phone_request(const char *type, int format, void *data, int *cause)
+static struct ast_channel *phone_request(const char *type, int format, const struct ast_channel *requestor, void *data, int *cause)
{
int oldformat;
struct phone_pvt *p;
@@ -1232,7 +1232,7 @@ static struct ast_channel *phone_request(const char *type, int format, void *dat
if (strncmp(name, p->dev + 5, length) == 0 &&
!isalnum(name[length])) {
if (!p->owner) {
- tmp = phone_new(p, AST_STATE_DOWN, p->context);
+ tmp = phone_new(p, AST_STATE_DOWN, p->context, requestor ? requestor->linkedid : NULL);
break;
} else
*cause = AST_CAUSE_BUSY;
diff --git a/channels/chan_sip.c b/channels/chan_sip.c
index 4a7d00ef9..00042ebe5 100644
--- a/channels/chan_sip.c
+++ b/channels/chan_sip.c
@@ -272,6 +272,7 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
#include "asterisk/event.h"
#include "asterisk/tcptls.h"
#include "asterisk/stun.h"
+#include "asterisk/cel.h"
/*** DOCUMENTATION
<application name="SIPDtmfMode" language="en_US">
@@ -2339,7 +2340,7 @@ enum t38_action_flag {
in coming releases. */
/*--- PBX interface functions */
-static struct ast_channel *sip_request_call(const char *type, int format, void *data, int *cause);
+static struct ast_channel *sip_request_call(const char *type, int format, const struct ast_channel *requestor, void *data, int *cause);
static int sip_devicestate(void *data);
static int sip_sendtext(struct ast_channel *ast, const char *text);
static int sip_call(struct ast_channel *ast, char *dest, int timeout);
@@ -5096,6 +5097,7 @@ static int create_addr_from_peer(struct sip_pvt *dialog, struct sip_peer *peer)
ast_string_field_set(dialog, mohinterpret, peer->mohinterpret);
ast_string_field_set(dialog, tohost, peer->tohost);
ast_string_field_set(dialog, fullcontact, peer->fullcontact);
+ ast_string_field_set(dialog, accountcode, peer->accountcode);
ast_string_field_set(dialog, context, peer->context);
ast_string_field_set(dialog, cid_num, peer->cid_num);
ast_string_field_set(dialog, cid_name, peer->cid_name);
@@ -6518,7 +6520,7 @@ static int sip_indicate(struct ast_channel *ast, int condition, const void *data
and from handle_request_invite for inbound channels
*/
-static struct ast_channel *sip_new(struct sip_pvt *i, int state, const char *title)
+static struct ast_channel *sip_new(struct sip_pvt *i, int state, const char *title, const char *linkedid)
{
struct ast_channel *tmp;
struct ast_variable *v = NULL;
@@ -6546,7 +6548,7 @@ static struct ast_channel *sip_new(struct sip_pvt *i, int state, const char *tit
sip_pvt_unlock(i);
/* Don't hold a sip pvt lock while we allocate a channel */
- tmp = ast_channel_alloc(1, state, i->cid_num, i->cid_name, i->accountcode, i->exten, i->context, i->amaflags, "SIP/%s-%08x", my_name, (int)(long) i);
+ tmp = ast_channel_alloc(1, state, i->cid_num, i->cid_name, i->accountcode, i->exten, i->context, linkedid, i->amaflags, "SIP/%s-%08x", my_name, (int)(long) i);
}
if (!tmp) {
@@ -17936,16 +17938,20 @@ static void handle_response_invite(struct sip_pvt *p, int resp, const char *rest
/* First we ACK */
xmitres = transmit_request(p, SIP_ACK, seqno, XMIT_UNRELIABLE, FALSE);
ast_log(LOG_WARNING, "Received response: \"Forbidden\" from '%s'\n", get_header(&p->initreq, "From"));
- if (!req->ignore && p->owner)
+ if (!req->ignore && p->owner) {
+ ast_set_hangupsource(p->owner, p->owner->name, 0);
ast_queue_control(p->owner, AST_CONTROL_CONGESTION);
+ }
pvt_set_needdestroy(p, "received 403 response");
sip_alreadygone(p);
break;
case 404: /* Not found */
xmitres = transmit_request(p, SIP_ACK, seqno, XMIT_UNRELIABLE, FALSE);
- if (p->owner && !req->ignore)
+ if (p->owner && !req->ignore) {
+ ast_set_hangupsource(p->owner, p->owner->name, 0);
ast_queue_control(p->owner, AST_CONTROL_CONGESTION);
+ }
sip_alreadygone(p);
break;
@@ -18983,8 +18989,8 @@ static int sip_park(struct ast_channel *chan1, struct ast_channel *chan2, struct
/* Chan2m: The transferer, chan1m: The transferee */
pthread_t th;
- transferee = ast_channel_alloc(0, AST_STATE_DOWN, 0, 0, chan1->accountcode, chan1->exten, chan1->context, chan1->amaflags, "Parking/%s", chan1->name);
- transferer = ast_channel_alloc(0, AST_STATE_DOWN, 0, 0, chan2->accountcode, chan2->exten, chan2->context, chan2->amaflags, "SIPPeer/%s", chan2->name);
+ transferee = ast_channel_alloc(0, AST_STATE_DOWN, 0, 0, chan1->accountcode, chan1->exten, chan1->context, chan1->linkedid, chan1->amaflags, "Parking/%s", chan1->name);
+ transferer = ast_channel_alloc(0, AST_STATE_DOWN, 0, 0, chan2->accountcode, chan2->exten, chan2->context, chan2->linkedid, chan2->amaflags, "SIPPeer/%s", chan2->name);
if ((!transferer) || (!transferee)) {
if (transferee) {
transferee->hangupcause = AST_CAUSE_SWITCH_CONGESTION;
@@ -20305,7 +20311,7 @@ static int handle_request_invite(struct sip_pvt *p, struct sip_request *req, int
make_our_tag(p->tag, sizeof(p->tag));
/* First invitation - create the channel */
- c = sip_new(p, AST_STATE_DOWN, S_OR(p->peername, NULL));
+ c = sip_new(p, AST_STATE_DOWN, S_OR(p->peername, NULL), NULL);
*recount = 1;
/* Save Record-Route for any later requests we make on this dialogue */
@@ -20625,6 +20631,7 @@ static int local_attended_transfer(struct sip_pvt *transferer, struct sip_dual *
struct sip_pvt *targetcall_pvt;
struct ast_party_connected_line connected_to_transferee;
struct ast_party_connected_line connected_to_target;
+ char transferer_linkedid[32];
/* Check if the call ID of the replaces header does exist locally */
if (!(targetcall_pvt = get_sip_pvt_byid_locked(transferer->refer->replaces_callid, transferer->refer->replaces_callid_totag,
@@ -20685,6 +20692,8 @@ static int local_attended_transfer(struct sip_pvt *transferer, struct sip_dual *
ast_set_flag(&transferer->flags[0], SIP_DEFER_BYE_ON_TRANSFER); /* Delay hangup */
+ ast_copy_string(transferer_linkedid, transferer->owner->linkedid, sizeof(transferer_linkedid));
+
/* Perform the transfer */
manager_event(EVENT_FLAG_CALL, "Transfer", "TransferMethod: SIP\r\nTransferType: Attended\r\nChannel: %s\r\nUniqueid: %s\r\nSIP-Callid: %s\r\nTargetChannel: %s\r\nTargetUniqueid: %s\r\n",
transferer->owner->name,
@@ -20712,6 +20721,14 @@ static int local_attended_transfer(struct sip_pvt *transferer, struct sip_dual *
/* Transfer succeeded! */
const char *xfersound = pbx_builtin_getvar_helper(target.chan1, "ATTENDED_TRANSFER_COMPLETE_SOUND");
+ while (ast_channel_trylock(target.chan1)) {
+ sip_pvt_unlock(targetcall_pvt);
+ sched_yield();
+ sip_pvt_lock(targetcall_pvt);
+ }
+ ast_cel_report_event(target.chan1, AST_CEL_ATTENDEDTRANSFER, NULL, transferer_linkedid, target.chan2);
+ ast_channel_unlock(target.chan1);
+
/* Tell transferer that we're done. */
transmit_notify_with_sipfrag(transferer, seqno, "200 OK", TRUE);
append_history(transferer, "Xfer", "Refer succeeded");
@@ -21075,6 +21092,17 @@ static int handle_request_refer(struct sip_pvt *p, struct sip_request *req, int
p->refer->refer_to, p->refer->refer_to_context);
/* Success - we have a new channel */
ast_debug(3, "%s transfer succeeded. Telling transferer.\n", p->refer->attendedtransfer? "Attended" : "Blind");
+
+ while (ast_channel_trylock(current.chan1)) {
+ sip_pvt_unlock(p);
+ sched_yield();
+ sip_pvt_lock(p);
+ }
+
+ /* XXX - what to we put in CEL 'extra' for attended transfers to external systems? NULL for now */
+ ast_cel_report_event(current.chan1, p->refer->attendedtransfer? AST_CEL_ATTENDEDTRANSFER : AST_CEL_BLINDTRANSFER, NULL, p->refer->attendedtransfer ? NULL : p->refer->refer_to, current.chan2);
+ ast_channel_unlock(current.chan1);
+
transmit_notify_with_sipfrag(p, seqno, "200 Ok", TRUE);
if (p->refer->localtransfer)
p->refer->status = REFER_200OK;
@@ -21126,8 +21154,10 @@ static int handle_request_cancel(struct sip_pvt *p, struct sip_request *req)
update_call_counter(p, DEC_CALL_LIMIT);
stop_media_flows(p); /* Immediately stop RTP, VRTP and UDPTL as applicable */
- if (p->owner)
+ if (p->owner) {
+ ast_set_hangupsource(p->owner, p->owner->name, 0);
ast_queue_hangup(p->owner);
+ }
else
sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
if (p->initreq.len > 0) {
@@ -21392,6 +21422,7 @@ static int handle_request_bye(struct sip_pvt *p, struct sip_request *req)
ast_queue_hangup_with_cause(p->owner, AST_CAUSE_PROTOCOL_ERROR);
}
} else if (p->owner) {
+ ast_set_hangupsource(p->owner, p->owner->name, 0);
ast_queue_hangup(p->owner);
ast_debug(3, "Received bye, issuing owner hangup\n");
} else {
@@ -21421,7 +21452,7 @@ static void add_peer_mwi_subs(struct sip_peer *peer)
struct sip_mailbox *mailbox;
AST_LIST_TRAVERSE(&peer->mailboxes, mailbox, entry) {
- mailbox->event_sub = ast_event_subscribe(AST_EVENT_MWI, mwi_event_cb, peer,
+ mailbox->event_sub = ast_event_subscribe(AST_EVENT_MWI, mwi_event_cb, "SIP mbox event", peer,
AST_EVENT_IE_MAILBOX, AST_EVENT_IE_PLTYPE_STR, mailbox->mailbox,
AST_EVENT_IE_CONTEXT, AST_EVENT_IE_PLTYPE_STR, S_OR(mailbox->context, "default"),
AST_EVENT_IE_END);
@@ -23248,7 +23279,7 @@ static int sip_devicestate(void *data)
* or SIP/host!dnid
* \endverbatim
*/
-static struct ast_channel *sip_request_call(const char *type, int format, void *data, int *cause)
+static struct ast_channel *sip_request_call(const char *type, int format, const struct ast_channel *requestor, void *data, int *cause)
{
struct sip_pvt *p;
struct ast_channel *tmpc = NULL;
@@ -23394,7 +23425,7 @@ static struct ast_channel *sip_request_call(const char *type, int format, void *
p->prefcodec = oldformat; /* Format for this call */
p->jointcapability = oldformat;
sip_pvt_lock(p);
- tmpc = sip_new(p, AST_STATE_DOWN, host); /* Place the call */
+ tmpc = sip_new(p, AST_STATE_DOWN, host, requestor ? requestor->linkedid : NULL); /* Place the call */
if (sip_cfg.callevents)
manager_event(EVENT_FLAG_SYSTEM, "ChannelUpdate",
"Channel: %s\r\nChanneltype: %s\r\nSIPcallid: %s\r\nSIPfullcontact: %s\r\nPeername: %s\r\n",
diff --git a/channels/chan_skinny.c b/channels/chan_skinny.c
index 7271a2ee0..d88739b86 100644
--- a/channels/chan_skinny.c
+++ b/channels/chan_skinny.c
@@ -1371,9 +1371,9 @@ struct skinnysession {
AST_LIST_ENTRY(skinnysession) list;
};
+static struct ast_channel *skinny_request(const char *type, int format, const struct ast_channel *requestor, void *data, int *cause);
static AST_LIST_HEAD_STATIC(sessions, skinnysession);
-static struct ast_channel *skinny_request(const char *type, int format, void *data, int *cause);
static int skinny_devicestate(void *data);
static int skinny_call(struct ast_channel *ast, char *dest, int timeout);
static int skinny_hangup(struct ast_channel *ast);
@@ -4348,7 +4348,7 @@ static int skinny_indicate(struct ast_channel *ast, int ind, const void *data, s
return 0;
}
-static struct ast_channel *skinny_new(struct skinny_line *l, int state)
+static struct ast_channel *skinny_new(struct skinny_line *l, int state, const char *linkedid)
{
struct ast_channel *tmp;
struct skinny_subchannel *sub;
@@ -4361,7 +4361,7 @@ static struct ast_channel *skinny_new(struct skinny_line *l, int state)
return NULL;
}
- tmp = ast_channel_alloc(1, state, l->cid_num, l->cid_name, l->accountcode, l->exten, l->context, l->amaflags, "Skinny/%s@%s-%d", l->name, d->name, callnums);
+ tmp = ast_channel_alloc(1, state, l->cid_num, l->cid_name, l->accountcode, l->exten, l->context, linkedid, l->amaflags, "Skinny/%s@%s-%d", l->name, d->name, callnums);
if (!tmp) {
ast_log(LOG_WARNING, "Unable to allocate channel structure\n");
return NULL;
@@ -4544,7 +4544,7 @@ static int handle_transfer_button(struct skinny_subchannel *sub)
if (!sub->onhold) {
skinny_hold(sub);
}
- c = skinny_new(l, AST_STATE_DOWN);
+ c = skinny_new(l, AST_STATE_DOWN, NULL);
if (c) {
newsub = c->tech_pvt;
/* point the sub and newsub at each other so we know they are related */
@@ -4822,7 +4822,7 @@ static int handle_stimulus_message(struct skinny_req *req, struct skinnysession
break;
}
- c = skinny_new(l, AST_STATE_DOWN);
+ c = skinny_new(l, AST_STATE_DOWN, NULL);
if (!c) {
ast_log(LOG_WARNING, "Unable to create channel for %s@%s\n", l->name, d->name);
} else {
@@ -4860,7 +4860,7 @@ static int handle_stimulus_message(struct skinny_req *req, struct skinnysession
}
if (!sub || !sub->owner)
- c = skinny_new(l, AST_STATE_DOWN);
+ c = skinny_new(l, AST_STATE_DOWN, NULL);
else
c = sub->owner;
@@ -4920,7 +4920,7 @@ static int handle_stimulus_message(struct skinny_req *req, struct skinnysession
ast_verb(1, "Received Stimulus: Voicemail(%d/%d)\n", instance, callreference);
if (!sub || !sub->owner) {
- c = skinny_new(l, AST_STATE_DOWN);
+ c = skinny_new(l, AST_STATE_DOWN, NULL);
} else {
c = sub->owner;
}
@@ -5005,7 +5005,7 @@ static int handle_stimulus_message(struct skinny_req *req, struct skinnysession
ast_verb(1, "Received Stimulus: Forward All(%d/%d)\n", instance, callreference);
if (!sub || !sub->owner) {
- c = skinny_new(l, AST_STATE_DOWN);
+ c = skinny_new(l, AST_STATE_DOWN, NULL);
} else {
c = sub->owner;
}
@@ -5022,7 +5022,7 @@ static int handle_stimulus_message(struct skinny_req *req, struct skinnysession
ast_verb(1, "Received Stimulus: Forward Busy (%d/%d)\n", instance, callreference);
if (!sub || !sub->owner) {
- c = skinny_new(l, AST_STATE_DOWN);
+ c = skinny_new(l, AST_STATE_DOWN, NULL);
} else {
c = sub->owner;
}
@@ -5040,7 +5040,7 @@ static int handle_stimulus_message(struct skinny_req *req, struct skinnysession
#if 0 /* Not sure how to handle this yet */
if (!sub || !sub->owner) {
- c = skinny_new(l, AST_STATE_DOWN);
+ c = skinny_new(l, AST_STATE_DOWN, NULL);
} else {
c = sub->owner;
}
@@ -5091,7 +5091,7 @@ static int handle_stimulus_message(struct skinny_req *req, struct skinnysession
if (sub && sub->owner) {
ast_debug(1, "Current subchannel [%s] already has owner\n", sub->owner->name);
} else {
- c = skinny_new(l, AST_STATE_DOWN);
+ c = skinny_new(l, AST_STATE_DOWN, NULL);
if (c) {
sub = c->tech_pvt;
l->activesub = sub;
@@ -5189,7 +5189,7 @@ static int handle_offhook_message(struct skinny_req *req, struct skinnysession *
if (sub && sub->owner) {
ast_debug(1, "Current sub [%s] already has owner\n", sub->owner->name);
} else {
- c = skinny_new(l, AST_STATE_DOWN);
+ c = skinny_new(l, AST_STATE_DOWN, NULL);
if (c) {
sub = c->tech_pvt;
l->activesub = sub;
@@ -5678,7 +5678,7 @@ static int handle_enbloc_call_message(struct skinny_req *req, struct skinnysessi
l = sub->parent;
}
- c = skinny_new(l, AST_STATE_DOWN);
+ c = skinny_new(l, AST_STATE_DOWN, NULL);
if(!c) {
ast_log(LOG_WARNING, "Unable to create channel for %s@%s\n", l->name, d->name);
@@ -5792,7 +5792,7 @@ static int handle_soft_key_event_message(struct skinny_req *req, struct skinnyse
}
if (!sub || !sub->owner) {
- c = skinny_new(l, AST_STATE_DOWN);
+ c = skinny_new(l, AST_STATE_DOWN, NULL);
} else {
c = sub->owner;
}
@@ -5828,7 +5828,7 @@ static int handle_soft_key_event_message(struct skinny_req *req, struct skinnyse
ast_verb(1, "Received Softkey Event: New Call(%d/%d)\n", instance, callreference);
/* New Call ALWAYS gets a new sub-channel */
- c = skinny_new(l, AST_STATE_DOWN);
+ c = skinny_new(l, AST_STATE_DOWN, NULL);
sub = c->tech_pvt;
/* transmit_ringer_mode(d, SKINNY_RING_OFF);
@@ -5898,7 +5898,7 @@ static int handle_soft_key_event_message(struct skinny_req *req, struct skinnyse
ast_verb(1, "Received Softkey Event: Forward All(%d/%d)\n", instance, callreference);
if (!sub || !sub->owner) {
- c = skinny_new(l, AST_STATE_DOWN);
+ c = skinny_new(l, AST_STATE_DOWN, NULL);
} else {
c = sub->owner;
}
@@ -5916,7 +5916,7 @@ static int handle_soft_key_event_message(struct skinny_req *req, struct skinnyse
ast_verb(1, "Received Softkey Event: Forward Busy (%d/%d)\n", instance, callreference);
if (!sub || !sub->owner) {
- c = skinny_new(l, AST_STATE_DOWN);
+ c = skinny_new(l, AST_STATE_DOWN, NULL);
} else {
c = sub->owner;
}
@@ -5935,7 +5935,7 @@ static int handle_soft_key_event_message(struct skinny_req *req, struct skinnyse
#if 0 /* Not sure how to handle this yet */
if (!sub || !sub->owner) {
- c = skinny_new(l, AST_STATE_DOWN);
+ c = skinny_new(l, AST_STATE_DOWN, NULL);
} else {
c = sub->owner;
}
@@ -6565,7 +6565,7 @@ static int skinny_devicestate(void *data)
return get_devicestate(l);
}
-static struct ast_channel *skinny_request(const char *type, int format, void *data, int *cause)
+static struct ast_channel *skinny_request(const char *type, int format, const struct ast_channel *requestor, void *data, int *cause)
{
int oldformat;
@@ -6592,7 +6592,7 @@ static struct ast_channel *skinny_request(const char *type, int format, void *da
return NULL;
}
ast_verb(3, "skinny_request(%s)\n", tmp);
- tmpc = skinny_new(l, AST_STATE_DOWN);
+ tmpc = skinny_new(l, AST_STATE_DOWN, requestor ? requestor->linkedid : NULL);
if (!tmpc) {
ast_log(LOG_WARNING, "Unable to make channel for '%s'\n", tmp);
}
@@ -7020,7 +7020,7 @@ static struct ast_channel *skinny_request(const char *type, int format, void *da
strsep(&cfg_context, "@");
if (ast_strlen_zero(cfg_context))
cfg_context = "default";
- l->mwi_event_sub = ast_event_subscribe(AST_EVENT_MWI, mwi_event_cb, l,
+ l->mwi_event_sub = ast_event_subscribe(AST_EVENT_MWI, mwi_event_cb, "skinny MWI subsciption", l,
AST_EVENT_IE_MAILBOX, AST_EVENT_IE_PLTYPE_STR, cfg_mailbox,
AST_EVENT_IE_CONTEXT, AST_EVENT_IE_PLTYPE_STR, cfg_context,
AST_EVENT_IE_NEWMSGS, AST_EVENT_IE_PLTYPE_EXISTS,
diff --git a/channels/chan_unistim.c b/channels/chan_unistim.c
index 27e8e0cb2..bb90301f9 100644
--- a/channels/chan_unistim.c
+++ b/channels/chan_unistim.c
@@ -670,13 +670,13 @@ static const char tdesc[] = "UNISTIM Channel Driver";
static const char channel_type[] = "USTM";
/*! Protos */
-static struct ast_channel *unistim_new(struct unistim_subchannel *sub, int state);
+static struct ast_channel *unistim_new(struct unistim_subchannel *sub, int state, const char *linkedid);
static int load_module(void);
static int reload(void);
static int unload_module(void);
static int reload_config(void);
static void show_main_page(struct unistimsession *pte);
-static struct ast_channel *unistim_request(const char *type, int format,
+static struct ast_channel *unistim_request(const char *type, int format, const struct ast_channel *requestor,
void *data, int *cause);
static int unistim_call(struct ast_channel *ast, char *dest, int timeout);
static int unistim_hangup(struct ast_channel *ast);
@@ -2363,7 +2363,7 @@ static void HandleCallOutgoing(struct unistimsession *s)
return;
}
if (!sub->owner) { /* A call is already in progress ? */
- c = unistim_new(sub, AST_STATE_DOWN); /* No, starting a new one */
+ c = unistim_new(sub, AST_STATE_DOWN, NULL); /* No, starting a new one */
if (c) {
/* Need to start RTP before calling ast_pbx_run */
if (!sub->rtp)
@@ -2411,7 +2411,7 @@ static void HandleCallOutgoing(struct unistimsession *s)
}
send_tone(s, 0, 0);
/* Make new channel */
- c = unistim_new(p->subs[SUB_THREEWAY], AST_STATE_DOWN);
+ c = unistim_new(p->subs[SUB_THREEWAY], AST_STATE_DOWN, NULL);
if (!c) {
ast_log(LOG_WARNING, "Cannot allocate new structure on channel %p\n", p);
return;
@@ -4422,7 +4422,7 @@ static int unistim_send_mwi_to_peer(struct unistimsession *s, unsigned int tick)
/*--- unistim_new: Initiate a call in the UNISTIM channel */
/* called from unistim_request (calls from the pbx ) */
-static struct ast_channel *unistim_new(struct unistim_subchannel *sub, int state)
+static struct ast_channel *unistim_new(struct unistim_subchannel *sub, int state, const char *linkedid)
{
struct ast_channel *tmp;
struct unistim_line *l;
@@ -4438,7 +4438,7 @@ static struct ast_channel *unistim_new(struct unistim_subchannel *sub, int state
}
l = sub->parent;
tmp = ast_channel_alloc(1, state, l->cid_num, NULL, l->accountcode, l->exten,
- l->context, l->amaflags, "%s@%s-%d", l->name, l->parent->name, sub->subtype);
+ l->context, linkedid, l->amaflags, "%s@%s-%d", l->name, l->parent->name, sub->subtype);
if (unistimdebug)
ast_verb(0, "unistim_new sub=%d (%p) chan=%p\n", sub->subtype, sub, tmp);
if (!tmp) {
@@ -4617,7 +4617,7 @@ static int restart_monitor(void)
/*--- unistim_request: PBX interface function ---*/
/* UNISTIM calls initiated by the PBX arrive here */
-static struct ast_channel *unistim_request(const char *type, int format, void *data,
+static struct ast_channel *unistim_request(const char *type, int format, const struct ast_channel *requestor, void *data,
int *cause)
{
int oldformat;
@@ -4660,7 +4660,7 @@ static struct ast_channel *unistim_request(const char *type, int format, void *d
return NULL;
}
sub->parent->capability = format;
- tmpc = unistim_new(sub, AST_STATE_DOWN);
+ tmpc = unistim_new(sub, AST_STATE_DOWN, requestor ? requestor->linkedid : NULL);
if (!tmpc)
ast_log(LOG_WARNING, "Unable to make channel for '%s'\n", tmp);
if (unistimdebug)
diff --git a/channels/chan_usbradio.c b/channels/chan_usbradio.c
index 2a829a685..b8e9d70a9 100644
--- a/channels/chan_usbradio.c
+++ b/channels/chan_usbradio.c
@@ -666,8 +666,9 @@ static char *usbradio_active; /* the active device */
static int setformat(struct chan_usbradio_pvt *o, int mode);
-static struct ast_channel *usbradio_request(const char *type, int format, void *data
-, int *cause);
+static struct ast_channel *usbradio_request(const char *type, int format,
+ const struct ast_channel *requestor,
+ void *data, int *cause);
static int usbradio_digit_begin(struct ast_channel *c, char digit);
static int usbradio_digit_end(struct ast_channel *c, char digit, unsigned int duration);
static int usbradio_text(struct ast_channel *c, const char *text);
@@ -2186,11 +2187,11 @@ static int usbradio_indicate(struct ast_channel *c, int cond, const void *data,
/*
* allocate a new channel.
*/
-static struct ast_channel *usbradio_new(struct chan_usbradio_pvt *o, char *ext, char *ctx, int state)
+static struct ast_channel *usbradio_new(struct chan_usbradio_pvt *o, char *ext, char *ctx, int state, const char *linkedid)
{
struct ast_channel *c;
- c = ast_channel_alloc(1, state, o->cid_num, o->cid_name, "", ext, ctx, 0, "Radio/%s", o->name);
+ c = ast_channel_alloc(1, state, o->cid_num, o->cid_name, "", ext, ctx, linkedid, 0, "Radio/%s", o->name);
if (c == NULL)
return NULL;
c->tech = &usbradio_tech;
@@ -2229,7 +2230,7 @@ static struct ast_channel *usbradio_new(struct chan_usbradio_pvt *o, char *ext,
}
/*
*/
-static struct ast_channel *usbradio_request(const char *type, int format, void *data, int *cause)
+static struct ast_channel *usbradio_request(const char *type, int format, const struct ast_channel *requestor, void *data, int *cause)
{
struct ast_channel *c;
struct chan_usbradio_pvt *o = find_desc(data);
@@ -2254,7 +2255,7 @@ static struct ast_channel *usbradio_request(const char *type, int format, void *
*cause = AST_CAUSE_BUSY;
return NULL;
}
- c = usbradio_new(o, NULL, NULL, AST_STATE_DOWN);
+ c = usbradio_new(o, NULL, NULL, AST_STATE_DOWN, requestor ? requestor->linkedid : NULL);
if (c == NULL) {
ast_log(LOG_WARNING, "Unable to create new usb channel\n");
return NULL;
diff --git a/channels/chan_vpb.cc b/channels/chan_vpb.cc
index e611ab097..fa82437c0 100644
--- a/channels/chan_vpb.cc
+++ b/channels/chan_vpb.cc
@@ -329,9 +329,9 @@ static struct vpb_pvt {
} *iflist = NULL;
-static struct ast_channel *vpb_new(struct vpb_pvt *i, enum ast_channel_state state, const char *context);
+static struct ast_channel *vpb_new(struct vpb_pvt *i, enum ast_channel_state state, const char *context, const char *linkedid);
static void *do_chanreads(void *pvt);
-static struct ast_channel *vpb_request(const char *type, int format, void *data, int *cause);
+static struct ast_channel *vpb_request(const char *type, int format, const struct ast_channel *requestor, void *data, int *cause);
static int vpb_digit_begin(struct ast_channel *ast, char digit);
static int vpb_digit_end(struct ast_channel *ast, char digit, unsigned int duration);
static int vpb_call(struct ast_channel *ast, char *dest, int timeout);
@@ -1116,7 +1116,7 @@ static inline int monitor_handle_notowned(struct vpb_pvt *p, VPB_EVENT *e)
break;
case VPB_RING:
if (p->mode == MODE_FXO) /* FXO port ring, start * */ {
- vpb_new(p, AST_STATE_RING, p->context);
+ vpb_new(p, AST_STATE_RING, p->context, NULL);
if (UsePolarityCID != 1) {
if (p->callerid_type == 1) {
ast_verb(4, "Using VPB Caller ID\n");
@@ -1140,7 +1140,7 @@ static inline int monitor_handle_notowned(struct vpb_pvt *p, VPB_EVENT *e)
case VPB_STATION_OFFHOOK:
if (p->mode == MODE_IMMEDIATE) {
- vpb_new(p,AST_STATE_RING, p->context);
+ vpb_new(p,AST_STATE_RING, p->context, NULL);
} else {
ast_verb(4, "%s: handle_notowned: playing dialtone\n", p->dev);
playtone(p->handle, &Dialtone);
@@ -1185,7 +1185,7 @@ static inline int monitor_handle_notowned(struct vpb_pvt *p, VPB_EVENT *e)
if (ast_exists_extension(NULL, p->context, p->ext, 1, p->callerid)){
ast_verb(4, "%s: handle_notowned: DTMF IDD timer out, matching on [%s] in [%s]\n", p->dev, p->ext, p->context);
- vpb_new(p, AST_STATE_RING, p->context);
+ vpb_new(p, AST_STATE_RING, p->context, NULL);
}
} else if (e->data == p->ring_timer_id) {
/* We didnt get another ring in time! */
@@ -1261,11 +1261,11 @@ static inline int monitor_handle_notowned(struct vpb_pvt *p, VPB_EVENT *e)
vpb_timer_start(p->dtmfidd_timer);
} else {
ast_verb(4, "%s: handle_notowned: Matched on [%s] in [%s]\n", p->dev, p->ext , p->context);
- vpb_new(p, AST_STATE_UP, p->context);
+ vpb_new(p, AST_STATE_UP, p->context, NULL);
}
} else if (!ast_canmatch_extension(NULL, p->context, p->ext, 1, p->callerid)) {
if (ast_exists_extension(NULL, "default", p->ext, 1, p->callerid)) {
- vpb_new(p, AST_STATE_UP, "default");
+ vpb_new(p, AST_STATE_UP, "default", NULL);
} else if (!ast_canmatch_extension(NULL, "default", p->ext, 1, p->callerid)) {
ast_verb(4, "%s: handle_notowned: can't match anything in %s or default\n", p->dev, p->context);
playtone(p->handle, &Busytone);
@@ -2466,7 +2466,7 @@ static void *do_chanreads(void *pvt)
return NULL;
}
-static struct ast_channel *vpb_new(struct vpb_pvt *me, enum ast_channel_state state, const char *context)
+static struct ast_channel *vpb_new(struct vpb_pvt *me, enum ast_channel_state state, const char *context, const char *linkedid)
{
struct ast_channel *tmp;
char cid_num[256];
@@ -2478,7 +2478,7 @@ static struct ast_channel *vpb_new(struct vpb_pvt *me, enum ast_channel_state st
}
ast_verb(4, "%s: New call for context [%s]\n", me->dev, context);
- tmp = ast_channel_alloc(1, state, 0, 0, "", me->ext, me->context, 0, "%s", me->dev);
+ tmp = ast_channel_alloc(1, state, 0, 0, "", me->ext, me->context, linkedid, 0, "%s", me->dev);
if (tmp) {
if (use_ast_ind == 1){
tmp->tech = &vpb_tech_indicate;
@@ -2541,7 +2541,7 @@ static struct ast_channel *vpb_new(struct vpb_pvt *me, enum ast_channel_state st
return tmp;
}
-static struct ast_channel *vpb_request(const char *type, int format, void *vdata, int *cause)
+static struct ast_channel *vpb_request(const char *type, int format, const struct ast_channel *requestor, void *vdata, int *cause)
{
int oldformat;
struct vpb_pvt *p;
@@ -2573,13 +2573,13 @@ static struct ast_channel *vpb_request(const char *type, int format, void *vdata
if (group == -1) {
if (strncmp(s, p->dev + 4, sizeof p->dev) == 0) {
if (!p->owner) {
- tmp = vpb_new(p, AST_STATE_DOWN, p->context);
+ tmp = vpb_new(p, AST_STATE_DOWN, p->context, requestor ? requestor->linkedid : NULL);
break;
}
}
} else {
if ((p->group == group) && (!p->owner)) {
- tmp = vpb_new(p, AST_STATE_DOWN, p->context);
+ tmp = vpb_new(p, AST_STATE_DOWN, p->context, requestor ? requestor->linkedid : NULL);
break;
}
}
diff --git a/channels/sig_analog.c b/channels/sig_analog.c
index da7b713e0..79fc27606 100644
--- a/channels/sig_analog.c
+++ b/channels/sig_analog.c
@@ -349,12 +349,12 @@ static int analog_play_tone(struct analog_pvt *p, enum analog_sub sub, enum anal
return -1;
}
-static struct ast_channel * analog_new_ast_channel(struct analog_pvt *p, int state, int startpbx, enum analog_sub sub)
+static struct ast_channel * analog_new_ast_channel(struct analog_pvt *p, int state, int startpbx, enum analog_sub sub, const struct ast_channel *requestor)
{
struct ast_channel *c;
if (p->calls->new_ast_channel)
- c = p->calls->new_ast_channel(p->chan_pvt, state, startpbx, sub);
+ c = p->calls->new_ast_channel(p->chan_pvt, state, startpbx, sub, requestor);
else
return NULL;
@@ -568,7 +568,7 @@ static int analog_update_conf(struct analog_pvt *p)
return 0;
}
-struct ast_channel * analog_request(struct analog_pvt *p, int *callwait)
+struct ast_channel * analog_request(struct analog_pvt *p, int *callwait, const struct ast_channel *requestor)
{
ast_log(LOG_DEBUG, "%s %d\n", __FUNCTION__, p->channel);
*callwait = (p->owner != NULL);
@@ -580,7 +580,7 @@ struct ast_channel * analog_request(struct analog_pvt *p, int *callwait)
}
}
- return analog_new_ast_channel(p, AST_STATE_RESERVED, 0, p->owner ? ANALOG_SUB_CALLWAIT : ANALOG_SUB_REAL);
+ return analog_new_ast_channel(p, AST_STATE_RESERVED, 0, p->owner ? ANALOG_SUB_CALLWAIT : ANALOG_SUB_REAL, requestor);
}
int analog_available(struct analog_pvt *p, int channelmatch, ast_group_t groupmatch, int *busy, int *channelmatched, int *groupmatched)
@@ -2623,7 +2623,7 @@ static struct ast_frame *__analog_handle_event(struct analog_pvt *p, struct ast_
goto winkflashdone;
}
/* Make new channel */
- chan = analog_new_ast_channel(p, AST_STATE_RESERVED, 0, ANALOG_SUB_THREEWAY);
+ chan = analog_new_ast_channel(p, AST_STATE_RESERVED, 0, ANALOG_SUB_THREEWAY, NULL);
if (p->dahditrcallerid) {
if (!p->origcid_num)
p->origcid_num = ast_strdup(p->cid_num);
@@ -3000,7 +3000,7 @@ int analog_handle_init_event(struct analog_pvt *i, int event)
analog_set_echocanceller(i, 1);
/* The channel is immediately up. Start right away */
res = analog_play_tone(i, ANALOG_SUB_REAL, ANALOG_TONE_RINGTONE);
- chan = analog_new_ast_channel(i, AST_STATE_RING, 1, ANALOG_SUB_REAL);
+ chan = analog_new_ast_channel(i, AST_STATE_RING, 1, ANALOG_SUB_REAL, NULL);
if (!chan) {
ast_log(LOG_WARNING, "Unable to start PBX on channel %d\n", i->channel);
res = analog_play_tone(i, ANALOG_SUB_REAL, ANALOG_TONE_CONGESTION);
@@ -3009,7 +3009,7 @@ int analog_handle_init_event(struct analog_pvt *i, int event)
}
} else {
/* Check for callerid, digits, etc */
- chan = analog_new_ast_channel(i, AST_STATE_RESERVED, 0, ANALOG_SUB_REAL);
+ chan = analog_new_ast_channel(i, AST_STATE_RESERVED, 0, ANALOG_SUB_REAL, NULL);
i->ss_astchan = chan;
if (chan) {
if (analog_has_voicemail(i))
@@ -3053,9 +3053,9 @@ int analog_handle_init_event(struct analog_pvt *i, int event)
case ANALOG_SIG_SF:
/* Check for callerid, digits, etc */
if (i->cid_start == ANALOG_CID_START_POLARITY_IN) {
- chan = analog_new_ast_channel(i, AST_STATE_PRERING, 0, ANALOG_SUB_REAL);
+ chan = analog_new_ast_channel(i, AST_STATE_PRERING, 0, ANALOG_SUB_REAL, NULL);
} else {
- chan = analog_new_ast_channel(i, AST_STATE_RING, 0, ANALOG_SUB_REAL);
+ chan = analog_new_ast_channel(i, AST_STATE_RING, 0, ANALOG_SUB_REAL, NULL);
}
i->ss_astchan = chan;
if (chan && ast_pthread_create(&threadid, &attr, __analog_ss_thread, i)) {
@@ -3153,7 +3153,7 @@ int analog_handle_init_event(struct analog_pvt *i, int event)
ast_verbose(VERBOSE_PREFIX_2 "Starting post polarity "
"CID detection on channel %d\n",
i->channel);
- chan = analog_new_ast_channel(i, AST_STATE_PRERING, 0, ANALOG_SUB_REAL);
+ chan = analog_new_ast_channel(i, AST_STATE_PRERING, 0, ANALOG_SUB_REAL, NULL);
i->ss_astchan = chan;
if (chan && ast_pthread_create(&threadid, &attr, __analog_ss_thread, i)) {
ast_log(LOG_WARNING, "Unable to start simple switch thread on channel %d\n", i->channel);
diff --git a/channels/sig_analog.h b/channels/sig_analog.h
index 24c4d6c8f..661179881 100644
--- a/channels/sig_analog.h
+++ b/channels/sig_analog.h
@@ -163,7 +163,7 @@ struct analog_callback {
/*! This function is for swapping of the owners with the underlying subs. Typically it means you need to change the fds
* of the new owner to be the fds of the sub specified, for each of the two subs given */
void (* const swap_subs)(void *pvt, enum analog_sub a, struct ast_channel *new_a_owner, enum analog_sub b, struct ast_channel *new_b_owner);
- struct ast_channel * (* const new_ast_channel)(void *pvt, int state, int startpbx, enum analog_sub sub);
+ struct ast_channel * (* const new_ast_channel)(void *pvt, int state, int startpbx, enum analog_sub sub, const struct ast_channel *requestor);
/* Add the given sub to a conference */
int (* const conf_add)(void *pvt, enum analog_sub sub);
@@ -300,7 +300,7 @@ int analog_answer(struct analog_pvt *p, struct ast_channel *ast);
struct ast_frame *analog_exception(struct analog_pvt *p, struct ast_channel *ast);
-struct ast_channel * analog_request(struct analog_pvt *p, int *callwait);
+struct ast_channel * analog_request(struct analog_pvt *p, int *callwait, const struct ast_channel *requestor);
int analog_available(struct analog_pvt *p, int channelmatch, ast_group_t groupmatch, int *busy, int *channelmatched, int *groupmatched);
diff --git a/channels/sig_pri.c b/channels/sig_pri.c
index 1a648a124..f2eeb230e 100644
--- a/channels/sig_pri.c
+++ b/channels/sig_pri.c
@@ -143,12 +143,12 @@ static int sig_pri_play_tone(struct sig_pri_chan *p, enum sig_pri_tone tone)
return -1;
}
-static struct ast_channel *sig_pri_new_ast_channel(struct sig_pri_chan *p, int state, int startpbx, int ulaw, int transfercapability, char *exten)
+static struct ast_channel *sig_pri_new_ast_channel(struct sig_pri_chan *p, int state, int startpbx, int ulaw, int transfercapability, char *exten, const struct ast_channel *requestor)
{
struct ast_channel *c;
if (p->calls->new_ast_channel)
- c = p->calls->new_ast_channel(p->chan_pvt, state, startpbx, ulaw, transfercapability, exten);
+ c = p->calls->new_ast_channel(p->chan_pvt, state, startpbx, ulaw, transfercapability, exten, requestor);
else
return NULL;
@@ -160,11 +160,11 @@ static struct ast_channel *sig_pri_new_ast_channel(struct sig_pri_chan *p, int s
return c;
}
-struct ast_channel *sig_pri_request(struct sig_pri_chan *p, enum sig_pri_law law)
+struct ast_channel *sig_pri_request(struct sig_pri_chan *p, enum sig_pri_law law, const struct ast_channel *requestor)
{
ast_log(LOG_DEBUG, "%s %d\n", __FUNCTION__, p->channel);
- return sig_pri_new_ast_channel(p, AST_STATE_RESERVED, 0, law, 0, p->exten);
+ return sig_pri_new_ast_channel(p, AST_STATE_RESERVED, 0, law, 0, p->exten, requestor);
}
int pri_is_up(struct sig_pri_pri *pri)
@@ -704,7 +704,7 @@ static void *pri_dchannel(void *vpri)
if (ast_tvdiff_ms(ast_tvnow(), lastidle) > 1000) {
/* Don't create a new idle call more than once per second */
snprintf(idlen, sizeof(idlen), "%d/%s", pri->pvts[nextidle]->channel, pri->idledial);
- idle = sig_pri_request(pri->pvts[nextidle], AST_FORMAT_ULAW);
+ idle = sig_pri_request(pri->pvts[nextidle], AST_FORMAT_ULAW, NULL);
if (idle) {
pri->pvts[nextidle]->isidlecall = 1;
if (ast_pthread_create_background(&p, NULL, do_idle_thread, idle)) {
@@ -1140,7 +1140,7 @@ static void *pri_dchannel(void *vpri)
/* Release the PRI lock while we create the channel */
ast_mutex_unlock(&pri->lock);
- c = sig_pri_new_ast_channel(pri->pvts[chanpos], AST_STATE_RESERVED, 0, (e->ring.layer1 = PRI_LAYER_1_ALAW) ? SIG_PRI_ALAW : SIG_PRI_ULAW, e->ring.ctype, pri->pvts[chanpos]->exten);
+ c = sig_pri_new_ast_channel(pri->pvts[chanpos], AST_STATE_RESERVED, 0, (e->ring.layer1 = PRI_LAYER_1_ALAW) ? SIG_PRI_ALAW : SIG_PRI_ULAW, e->ring.ctype, pri->pvts[chanpos]->exten, NULL);
sig_pri_unlock_private(pri->pvts[chanpos]);
@@ -1187,7 +1187,7 @@ static void *pri_dchannel(void *vpri)
} else {
ast_mutex_unlock(&pri->lock);
/* Release PRI lock while we create the channel */
- c = sig_pri_new_ast_channel(pri->pvts[chanpos], AST_STATE_RING, 1, (e->ring.layer1 == PRI_LAYER_1_ALAW) ? SIG_PRI_ALAW : SIG_PRI_ULAW, e->ring.ctype, pri->pvts[chanpos]->exten);
+ c = sig_pri_new_ast_channel(pri->pvts[chanpos], AST_STATE_RING, 1, (e->ring.layer1 == PRI_LAYER_1_ALAW) ? SIG_PRI_ALAW : SIG_PRI_ULAW, e->ring.ctype, pri->pvts[chanpos]->exten, NULL);
if (c) {
char calledtonstr[10];
diff --git a/channels/sig_pri.h b/channels/sig_pri.h
index 2c9f7b6d7..80cfdd190 100644
--- a/channels/sig_pri.h
+++ b/channels/sig_pri.h
@@ -64,7 +64,7 @@ struct sig_pri_callback {
int (* const set_echocanceller)(void *pvt, int enable);
int (* const train_echocanceller)(void *pvt);
- struct ast_channel * (* const new_ast_channel)(void *pvt, int state, int startpbx, enum sig_pri_law law, int transfercapability, char *exten);
+ struct ast_channel * (* const new_ast_channel)(void *pvt, int state, int startpbx, enum sig_pri_law law, int transfercapability, char *exten, const struct ast_channel *chan);
void (* const fixup_chans)(void *old_chan, void *new_chan);
@@ -239,7 +239,7 @@ void pri_event_alarm(struct sig_pri_pri *pri, int index, int before_start_pri);
void pri_event_noalarm(struct sig_pri_pri *pri, int index, int before_start_pri);
-struct ast_channel *sig_pri_request(struct sig_pri_chan *p, enum sig_pri_law law);
+struct ast_channel *sig_pri_request(struct sig_pri_chan *p, enum sig_pri_law law, const struct ast_channel *requestor);
struct sig_pri_chan *sig_pri_chan_new(void *pvt_data, struct sig_pri_callback *callback, struct sig_pri_pri *pri, int logicalspan, int channo);