diff options
Diffstat (limited to 'channels')
-rw-r--r-- | channels/chan_agent.c | 18 | ||||
-rw-r--r-- | channels/chan_alsa.c | 12 | ||||
-rw-r--r-- | channels/chan_bridge.c | 8 | ||||
-rw-r--r-- | channels/chan_console.c | 14 | ||||
-rw-r--r-- | channels/chan_dahdi.c | 58 | ||||
-rw-r--r-- | channels/chan_gtalk.c | 12 | ||||
-rw-r--r-- | channels/chan_h323.c | 12 | ||||
-rw-r--r-- | channels/chan_iax2.c | 74 | ||||
-rw-r--r-- | channels/chan_jingle.c | 12 | ||||
-rw-r--r-- | channels/chan_local.c | 12 | ||||
-rw-r--r-- | channels/chan_mgcp.c | 16 | ||||
-rw-r--r-- | channels/chan_misdn.c | 14 | ||||
-rw-r--r-- | channels/chan_multicast_rtp.c | 6 | ||||
-rw-r--r-- | channels/chan_nbs.c | 10 | ||||
-rw-r--r-- | channels/chan_oss.c | 13 | ||||
-rw-r--r-- | channels/chan_phone.c | 18 | ||||
-rw-r--r-- | channels/chan_sip.c | 55 | ||||
-rw-r--r-- | channels/chan_skinny.c | 42 | ||||
-rw-r--r-- | channels/chan_unistim.c | 16 | ||||
-rw-r--r-- | channels/chan_usbradio.c | 13 | ||||
-rw-r--r-- | channels/chan_vpb.cc | 24 | ||||
-rw-r--r-- | channels/sig_analog.c | 20 | ||||
-rw-r--r-- | channels/sig_analog.h | 4 | ||||
-rw-r--r-- | channels/sig_pri.c | 14 | ||||
-rw-r--r-- | channels/sig_pri.h | 4 |
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); |