Display a list of channel variables in each channel-oriented event.

(Closes AST-33)
Reviewboard:	https://reviewboard.asterisk.org/r/368/


git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@230111 65c4cc65-6c06-0410-ace0-fbb531ad65f3
This commit is contained in:
Tilghman Lesher 2009-11-13 20:42:03 +00:00
parent 85dd68ca7a
commit 5e2aa190fe
18 changed files with 172 additions and 75 deletions

View File

@ -277,6 +277,9 @@ Asterisk Manager Interface
but options with the 'tls' prefix are preferred. but options with the 'tls' prefix are preferred.
* Added a MuteAudio AMI action for muting inbound and/or outbound audio * Added a MuteAudio AMI action for muting inbound and/or outbound audio
in a channel. (res_mutestream.so) in a channel. (res_mutestream.so)
* The configuration file manager.conf now supports a channelvars option, which
specifies a list of channel variables to include in each channel-oriented
event.
Channel Event Logging Channel Event Logging
--------------------- ---------------------

View File

@ -513,6 +513,7 @@ static int channel_spy(struct ast_channel *chan, struct ast_autochan *spyee_auto
struct ast_silence_generator *silgen = NULL; struct ast_silence_generator *silgen = NULL;
struct ast_autochan *spyee_bridge_autochan = NULL; struct ast_autochan *spyee_bridge_autochan = NULL;
const char *spyer_name; const char *spyer_name;
struct ast_channel *chans[] = { chan, spyee_autochan->chan };
ast_channel_lock(chan); ast_channel_lock(chan);
spyer_name = ast_strdupa(chan->name); spyer_name = ast_strdupa(chan->name);
@ -529,7 +530,7 @@ static int channel_spy(struct ast_channel *chan, struct ast_autochan *spyee_auto
ast_channel_unlock(spyee_autochan->chan); ast_channel_unlock(spyee_autochan->chan);
ast_verb(2, "Spying on channel %s\n", name); ast_verb(2, "Spying on channel %s\n", name);
manager_event(EVENT_FLAG_CALL, "ChanSpyStart", ast_manager_event_multichan(EVENT_FLAG_CALL, "ChanSpyStart", 2, chans,
"SpyerChannel: %s\r\n" "SpyerChannel: %s\r\n"
"SpyeeChannel: %s\r\n", "SpyeeChannel: %s\r\n",
spyer_name, name); spyer_name, name);
@ -697,7 +698,7 @@ static int channel_spy(struct ast_channel *chan, struct ast_autochan *spyee_auto
} }
ast_verb(2, "Done Spying on channel %s\n", name); ast_verb(2, "Done Spying on channel %s\n", name);
manager_event(EVENT_FLAG_CALL, "ChanSpyStop", "SpyeeChannel: %s\r\n", name); ast_manager_event(chan, EVENT_FLAG_CALL, "ChanSpyStop", "SpyeeChannel: %s\r\n", name);
return running; return running;
} }

View File

@ -722,7 +722,8 @@ static const char *get_cid_name(char *name, int namelen, struct ast_channel *cha
static void senddialevent(struct ast_channel *src, struct ast_channel *dst, const char *dialstring) static void senddialevent(struct ast_channel *src, struct ast_channel *dst, const char *dialstring)
{ {
manager_event(EVENT_FLAG_CALL, "Dial", struct ast_channel *chans[] = { src, dst };
ast_manager_event_multichan(EVENT_FLAG_CALL, "Dial", 2, chans,
"SubEvent: Begin\r\n" "SubEvent: Begin\r\n"
"Channel: %s\r\n" "Channel: %s\r\n"
"Destination: %s\r\n" "Destination: %s\r\n"
@ -736,9 +737,9 @@ static void senddialevent(struct ast_channel *src, struct ast_channel *dst, cons
dst->uniqueid, dialstring ? dialstring : ""); dst->uniqueid, dialstring ? dialstring : "");
} }
static void senddialendevent(const struct ast_channel *src, const char *dialstatus) static void senddialendevent(struct ast_channel *src, const char *dialstatus)
{ {
manager_event(EVENT_FLAG_CALL, "Dial", ast_manager_event(src, EVENT_FLAG_CALL, "Dial",
"SubEvent: End\r\n" "SubEvent: End\r\n"
"Channel: %s\r\n" "Channel: %s\r\n"
"UniqueID: %s\r\n" "UniqueID: %s\r\n"

View File

@ -248,7 +248,7 @@ static void phase_e_handler(t30_state_t *f, void *user_data, int result)
ast_debug(1, " Image resolution: %d x %d\n", stat.x_resolution, stat.y_resolution); ast_debug(1, " Image resolution: %d x %d\n", stat.x_resolution, stat.y_resolution);
ast_debug(1, " Transfer Rate: %d\n", stat.bit_rate); ast_debug(1, " Transfer Rate: %d\n", stat.bit_rate);
manager_event(EVENT_FLAG_CALL, ast_manager_event(s->chan, EVENT_FLAG_CALL,
s->direction ? "FaxSent" : "FaxReceived", s->direction ? "FaxSent" : "FaxReceived",
"Channel: %s\r\n" "Channel: %s\r\n"
"Exten: %s\r\n" "Exten: %s\r\n"

View File

@ -2508,7 +2508,7 @@ static int conf_run(struct ast_channel *chan, struct ast_conference *conf, int c
ast_debug(1, "Placed channel %s in DAHDI conf %d\n", chan->name, conf->dahdiconf); ast_debug(1, "Placed channel %s in DAHDI conf %d\n", chan->name, conf->dahdiconf);
if (!sent_event) { if (!sent_event) {
manager_event(EVENT_FLAG_CALL, "MeetmeJoin", ast_manager_event(chan, EVENT_FLAG_CALL, "MeetmeJoin",
"Channel: %s\r\n" "Channel: %s\r\n"
"Uniqueid: %s\r\n" "Uniqueid: %s\r\n"
"Meetme: %s\r\n" "Meetme: %s\r\n"
@ -2837,7 +2837,7 @@ static int conf_run(struct ast_channel *chan, struct ast_conference *conf, int c
break; break;
} }
manager_event(EVENT_FLAG_CALL, "MeetmeMute", ast_manager_event(chan, EVENT_FLAG_CALL, "MeetmeMute",
"Channel: %s\r\n" "Channel: %s\r\n"
"Uniqueid: %s\r\n" "Uniqueid: %s\r\n"
"Meetme: %s\r\n" "Meetme: %s\r\n"
@ -2855,7 +2855,7 @@ static int conf_run(struct ast_channel *chan, struct ast_conference *conf, int c
break; break;
} }
manager_event(EVENT_FLAG_CALL, "MeetmeMute", ast_manager_event(chan, EVENT_FLAG_CALL, "MeetmeMute",
"Channel: %s\r\n" "Channel: %s\r\n"
"Uniqueid: %s\r\n" "Uniqueid: %s\r\n"
"Meetme: %s\r\n" "Meetme: %s\r\n"
@ -2868,7 +2868,7 @@ static int conf_run(struct ast_channel *chan, struct ast_conference *conf, int c
(user->adminflags & ADMINFLAG_T_REQUEST) && !(talkreq_manager)) { (user->adminflags & ADMINFLAG_T_REQUEST) && !(talkreq_manager)) {
talkreq_manager = 1; talkreq_manager = 1;
manager_event(EVENT_FLAG_CALL, "MeetmeTalkRequest", ast_manager_event(chan, EVENT_FLAG_CALL, "MeetmeTalkRequest",
"Channel: %s\r\n" "Channel: %s\r\n"
"Uniqueid: %s\r\n" "Uniqueid: %s\r\n"
"Meetme: %s\r\n" "Meetme: %s\r\n"
@ -2881,7 +2881,7 @@ static int conf_run(struct ast_channel *chan, struct ast_conference *conf, int c
if (!(user->adminflags & (ADMINFLAG_MUTED | ADMINFLAG_SELFMUTED)) && if (!(user->adminflags & (ADMINFLAG_MUTED | ADMINFLAG_SELFMUTED)) &&
!(user->adminflags & ADMINFLAG_T_REQUEST) && (talkreq_manager)) { !(user->adminflags & ADMINFLAG_T_REQUEST) && (talkreq_manager)) {
talkreq_manager = 0; talkreq_manager = 0;
manager_event(EVENT_FLAG_CALL, "MeetmeTalkRequest", ast_manager_event(chan, EVENT_FLAG_CALL, "MeetmeTalkRequest",
"Channel: %s\r\n" "Channel: %s\r\n"
"Uniqueid: %s\r\n" "Uniqueid: %s\r\n"
"Meetme: %s\r\n" "Meetme: %s\r\n"
@ -2949,7 +2949,7 @@ static int conf_run(struct ast_channel *chan, struct ast_conference *conf, int c
if (!user->talking && totalsilence < MEETME_DELAYDETECTTALK) { if (!user->talking && totalsilence < MEETME_DELAYDETECTTALK) {
user->talking = 1; user->talking = 1;
if (confflags & CONFFLAG_MONITORTALKER) if (confflags & CONFFLAG_MONITORTALKER)
manager_event(EVENT_FLAG_CALL, "MeetmeTalking", ast_manager_event(chan, EVENT_FLAG_CALL, "MeetmeTalking",
"Channel: %s\r\n" "Channel: %s\r\n"
"Uniqueid: %s\r\n" "Uniqueid: %s\r\n"
"Meetme: %s\r\n" "Meetme: %s\r\n"
@ -2960,7 +2960,7 @@ static int conf_run(struct ast_channel *chan, struct ast_conference *conf, int c
if (user->talking && totalsilence > MEETME_DELAYDETECTENDTALK) { if (user->talking && totalsilence > MEETME_DELAYDETECTENDTALK) {
user->talking = 0; user->talking = 0;
if (confflags & CONFFLAG_MONITORTALKER) { if (confflags & CONFFLAG_MONITORTALKER) {
manager_event(EVENT_FLAG_CALL, "MeetmeTalking", ast_manager_event(chan, EVENT_FLAG_CALL, "MeetmeTalking",
"Channel: %s\r\n" "Channel: %s\r\n"
"Uniqueid: %s\r\n" "Uniqueid: %s\r\n"
"Meetme: %s\r\n" "Meetme: %s\r\n"
@ -3384,7 +3384,7 @@ bailoutandtrynormal:
sec = (now.tv_sec - user->jointime) % 60; sec = (now.tv_sec - user->jointime) % 60;
if (sent_event) { if (sent_event) {
manager_event(EVENT_FLAG_CALL, "MeetmeLeave", ast_manager_event(chan, EVENT_FLAG_CALL, "MeetmeLeave",
"Channel: %s\r\n" "Channel: %s\r\n"
"Uniqueid: %s\r\n" "Uniqueid: %s\r\n"
"Meetme: %s\r\n" "Meetme: %s\r\n"

View File

@ -1806,7 +1806,7 @@ static int notify_new_message(struct ast_channel *chan, const char *templatename
res = sendmail(etemplate, vmu, cidnum, cidname, filename, messageformat, duration, etemplate->attachment, MVM_MESSAGE_PAGE, counter); res = sendmail(etemplate, vmu, cidnum, cidname, filename, messageformat, duration, etemplate->attachment, MVM_MESSAGE_PAGE, counter);
} }
manager_event(EVENT_FLAG_CALL, "MiniVoiceMail", "Action: SentNotification\rn\nMailbox: %s@%s\r\nCounter: %s\r\n", vmu->username, vmu->domain, counter); ast_manager_event(chan, EVENT_FLAG_CALL, "MiniVoiceMail", "Action: SentNotification\rn\nMailbox: %s@%s\r\nCounter: %s\r\n", vmu->username, vmu->domain, counter);
run_externnotify(chan, vmu); /* Run external notification */ run_externnotify(chan, vmu); /* Run external notification */

View File

@ -2245,7 +2245,7 @@ static int join_queue(char *queuename, struct queue_ent *qe, enum queue_result *
ast_copy_string(qe->context, q->context, sizeof(qe->context)); ast_copy_string(qe->context, q->context, sizeof(qe->context));
q->count++; q->count++;
res = 0; res = 0;
manager_event(EVENT_FLAG_CALL, "Join", ast_manager_event(qe->chan, EVENT_FLAG_CALL, "Join",
"Channel: %s\r\nCallerIDNum: %s\r\nCallerIDName: %s\r\nQueue: %s\r\nPosition: %d\r\nCount: %d\r\nUniqueid: %s\r\n", "Channel: %s\r\nCallerIDNum: %s\r\nCallerIDName: %s\r\nQueue: %s\r\nPosition: %d\r\nCount: %d\r\nUniqueid: %s\r\n",
qe->chan->name, qe->chan->name,
S_OR(qe->chan->cid.cid_num, "unknown"), /* XXX somewhere else it is <unknown> */ S_OR(qe->chan->cid.cid_num, "unknown"), /* XXX somewhere else it is <unknown> */
@ -2498,7 +2498,7 @@ static void leave_queue(struct queue_ent *qe)
q->count--; q->count--;
/* Take us out of the queue */ /* Take us out of the queue */
manager_event(EVENT_FLAG_CALL, "Leave", ast_manager_event(qe->chan, EVENT_FLAG_CALL, "Leave",
"Channel: %s\r\nQueue: %s\r\nCount: %d\r\nPosition: %d\r\nUniqueid: %s\r\n", "Channel: %s\r\nQueue: %s\r\nCount: %d\r\nPosition: %d\r\nUniqueid: %s\r\n",
qe->chan->name, q->name, q->count, qe->pos, qe->chan->uniqueid); qe->chan->name, q->name, q->count, qe->pos, qe->chan->uniqueid);
ast_debug(1, "Queue '%s' Leave, Channel '%s'\n", q->name, qe->chan->name ); ast_debug(1, "Queue '%s' Leave, Channel '%s'\n", q->name, qe->chan->name );

View File

@ -6558,7 +6558,7 @@ static int notify_new_message(struct ast_channel *chan, struct ast_vm_user *vmu,
queue_mwi_event(ext_context, urgentmsgs, newmsgs, oldmsgs); queue_mwi_event(ext_context, urgentmsgs, newmsgs, oldmsgs);
manager_event(EVENT_FLAG_CALL, "MessageWaiting", "Mailbox: %s@%s\r\nWaiting: %d\r\nNew: %d\r\nOld: %d\r\n", vmu->mailbox, vmu->context, ast_app_has_voicemail(ext_context, NULL), newmsgs, oldmsgs); ast_manager_event(chan, EVENT_FLAG_CALL, "MessageWaiting", "Mailbox: %s@%s\r\nWaiting: %d\r\nNew: %d\r\nOld: %d\r\n", vmu->mailbox, vmu->context, ast_app_has_voicemail(ext_context, NULL), newmsgs, oldmsgs);
run_externnotify(vmu->context, vmu->mailbox, flag); run_externnotify(vmu->context, vmu->mailbox, flag);
#ifdef IMAP_STORAGE #ifdef IMAP_STORAGE
@ -9767,7 +9767,7 @@ out:
if (valid) { if (valid) {
int new = 0, old = 0, urgent = 0; int new = 0, old = 0, urgent = 0;
snprintf(ext_context, sizeof(ext_context), "%s@%s", vms.username, vmu->context); snprintf(ext_context, sizeof(ext_context), "%s@%s", vms.username, vmu->context);
manager_event(EVENT_FLAG_CALL, "MessageWaiting", "Mailbox: %s\r\nWaiting: %d\r\n", ext_context, has_voicemail(ext_context, NULL)); ast_manager_event(chan, EVENT_FLAG_CALL, "MessageWaiting", "Mailbox: %s\r\nWaiting: %d\r\n", ext_context, has_voicemail(ext_context, NULL));
/* Urgent flag not passwd to externnotify here */ /* Urgent flag not passwd to externnotify here */
run_externnotify(vmu->context, vmu->mailbox, NULL); run_externnotify(vmu->context, vmu->mailbox, NULL);
ast_app_inboxcount2(ext_context, &urgent, &new, &old); ast_app_inboxcount2(ext_context, &urgent, &new, &old);

View File

@ -10072,7 +10072,7 @@ retryowner:
if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED)) { if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED)) {
/* Generate Manager Hold event, if necessary*/ /* Generate Manager Hold event, if necessary*/
if (iaxs[fr->callno]->owner) { if (iaxs[fr->callno]->owner) {
manager_event(EVENT_FLAG_CALL, "Hold", ast_manager_event(iaxs[fr->callno]->owner, EVENT_FLAG_CALL, "Hold",
"Status: On\r\n" "Status: On\r\n"
"Channel: %s\r\n" "Channel: %s\r\n"
"Uniqueid: %s\r\n", "Uniqueid: %s\r\n",
@ -10099,7 +10099,7 @@ retryowner:
if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED)) { if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED)) {
/* Generate Manager Unhold event, if necessary*/ /* Generate Manager Unhold event, if necessary*/
if (iaxs[fr->callno]->owner && ast_test_flag64(iaxs[fr->callno], IAX_QUELCH)) { if (iaxs[fr->callno]->owner && ast_test_flag64(iaxs[fr->callno], IAX_QUELCH)) {
manager_event(EVENT_FLAG_CALL, "Hold", ast_manager_event(iaxs[fr->callno]->owner, EVENT_FLAG_CALL, "Hold",
"Status: Off\r\n" "Status: Off\r\n"
"Channel: %s\r\n" "Channel: %s\r\n"
"Uniqueid: %s\r\n", "Uniqueid: %s\r\n",

View File

@ -8863,7 +8863,7 @@ static int process_sdp(struct sip_pvt *p, struct sip_request *req, int t38action
/* Queue Manager Unhold event */ /* Queue Manager Unhold event */
append_history(p, "Unhold", "%s", req->data->str); append_history(p, "Unhold", "%s", req->data->str);
if (sip_cfg.callevents) if (sip_cfg.callevents)
manager_event(EVENT_FLAG_CALL, "Hold", ast_manager_event(p->owner, EVENT_FLAG_CALL, "Hold",
"Status: Off\r\n" "Status: Off\r\n"
"Channel: %s\r\n" "Channel: %s\r\n"
"Uniqueid: %s\r\n", "Uniqueid: %s\r\n",
@ -8885,7 +8885,7 @@ static int process_sdp(struct sip_pvt *p, struct sip_request *req, int t38action
/* Queue Manager Hold event */ /* Queue Manager Hold event */
append_history(p, "Hold", "%s", req->data->str); append_history(p, "Hold", "%s", req->data->str);
if (sip_cfg.callevents && !ast_test_flag(&p->flags[1], SIP_PAGE2_CALL_ONHOLD)) { if (sip_cfg.callevents && !ast_test_flag(&p->flags[1], SIP_PAGE2_CALL_ONHOLD)) {
manager_event(EVENT_FLAG_CALL, "Hold", ast_manager_event(p->owner, EVENT_FLAG_CALL, "Hold",
"Status: On\r\n" "Status: On\r\n"
"Channel: %s\r\n" "Channel: %s\r\n"
"Uniqueid: %s\r\n", "Uniqueid: %s\r\n",
@ -21352,6 +21352,7 @@ static int local_attended_transfer(struct sip_pvt *transferer, struct sip_dual *
struct ast_party_connected_line connected_to_transferee; struct ast_party_connected_line connected_to_transferee;
struct ast_party_connected_line connected_to_target; struct ast_party_connected_line connected_to_target;
char transferer_linkedid[32]; char transferer_linkedid[32];
struct ast_channel *chans[2];
/* Check if the call ID of the replaces header does exist locally */ /* 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, if (!(targetcall_pvt = get_sip_pvt_byid_locked(transferer->refer->replaces_callid, transferer->refer->replaces_callid_totag,
@ -21415,7 +21416,9 @@ static int local_attended_transfer(struct sip_pvt *transferer, struct sip_dual *
ast_copy_string(transferer_linkedid, transferer->owner->linkedid, sizeof(transferer_linkedid)); ast_copy_string(transferer_linkedid, transferer->owner->linkedid, sizeof(transferer_linkedid));
/* Perform the transfer */ /* 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", chans[0] = transferer->owner;
chans[1] = target.chan1;
ast_manager_event_multichan(EVENT_FLAG_CALL, "Transfer", 2, chans, "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, transferer->owner->name,
transferer->owner->uniqueid, transferer->owner->uniqueid,
transferer->callid, transferer->callid,
@ -21565,6 +21568,7 @@ static int handle_request_refer(struct sip_pvt *p, struct sip_request *req, int
/* Chan2: Call between asterisk and transferee */ /* Chan2: Call between asterisk and transferee */
int res = 0; int res = 0;
struct ast_channel *chans[2];
current.req.data = NULL; current.req.data = NULL;
if (req->debug) if (req->debug)
@ -21682,10 +21686,10 @@ static int handle_request_refer(struct sip_pvt *p, struct sip_request *req, int
/* Get the transferer's channel */ /* Get the transferer's channel */
current.chan1 = p->owner; chans[0] = current.chan1 = p->owner;
/* Find the other part of the bridge (2) - transferee */ /* Find the other part of the bridge (2) - transferee */
current.chan2 = ast_bridged_channel(current.chan1); chans[1] = current.chan2 = ast_bridged_channel(current.chan1);
if (sipdebug) if (sipdebug)
ast_debug(3, "SIP %s transfer: Transferer channel %s, transferee channel %s\n", p->refer->attendedtransfer ? "attended" : "blind", current.chan1->name, current.chan2 ? current.chan2->name : "<none>"); ast_debug(3, "SIP %s transfer: Transferer channel %s, transferee channel %s\n", p->refer->attendedtransfer ? "attended" : "blind", current.chan1->name, current.chan2 ? current.chan2->name : "<none>");
@ -21731,7 +21735,7 @@ static int handle_request_refer(struct sip_pvt *p, struct sip_request *req, int
ast_clear_flag(&p->flags[0], SIP_GOTREFER); ast_clear_flag(&p->flags[0], SIP_GOTREFER);
p->refer->status = REFER_200OK; p->refer->status = REFER_200OK;
append_history(p, "Xfer", "REFER to call parking."); append_history(p, "Xfer", "REFER to call parking.");
manager_event(EVENT_FLAG_CALL, "Transfer", "TransferMethod: SIP\r\nTransferType: Blind\r\nChannel: %s\r\nUniqueid: %s\r\nSIP-Callid: %s\r\nTargetChannel: %s\r\nTargetUniqueid: %s\r\nTransferExten: %s\r\nTransfer2Parking: Yes\r\n", ast_manager_event_multichan(EVENT_FLAG_CALL, "Transfer", 2, chans, "TransferMethod: SIP\r\nTransferType: Blind\r\nChannel: %s\r\nUniqueid: %s\r\nSIP-Callid: %s\r\nTargetChannel: %s\r\nTargetUniqueid: %s\r\nTransferExten: %s\r\nTransfer2Parking: Yes\r\n",
current.chan1->name, current.chan1->name,
current.chan1->uniqueid, current.chan1->uniqueid,
p->callid, p->callid,
@ -21809,7 +21813,7 @@ static int handle_request_refer(struct sip_pvt *p, struct sip_request *req, int
res = ast_async_goto(current.chan2, p->refer->refer_to_context, p->refer->refer_to, 1); res = ast_async_goto(current.chan2, p->refer->refer_to_context, p->refer->refer_to, 1);
if (!res) { if (!res) {
manager_event(EVENT_FLAG_CALL, "Transfer", "TransferMethod: SIP\r\nTransferType: Blind\r\nChannel: %s\r\nUniqueid: %s\r\nSIP-Callid: %s\r\nTargetChannel: %s\r\nTargetUniqueid: %s\r\nTransferExten: %s\r\nTransferContext: %s\r\n", ast_manager_event_multichan(EVENT_FLAG_CALL, "Transfer", 2, chans, "TransferMethod: SIP\r\nTransferType: Blind\r\nChannel: %s\r\nUniqueid: %s\r\nSIP-Callid: %s\r\nTargetChannel: %s\r\nTargetUniqueid: %s\r\nTransferExten: %s\r\nTransferContext: %s\r\n",
current.chan1->name, current.chan1->name,
current.chan1->uniqueid, current.chan1->uniqueid,
p->callid, p->callid,

View File

@ -57,6 +57,12 @@ bindaddr = 0.0.0.0
; ;
;timestampevents = yes ;timestampevents = yes
;
; Display certain channel variables every time a channel-oriented
; event is emitted:
;
;channelvars = var1,var2,var3
; debug = on ; enable some debugging info in AMI messages (default off). ; debug = on ; enable some debugging info in AMI messages (default off).
; Also accessible through the "manager debug" CLI command. ; Also accessible through the "manager debug" CLI command.
;[mark] ;[mark]

View File

@ -197,11 +197,26 @@ int astman_verify_session_writepermissions(uint32_t ident, int perm);
/* XXX the parser in gcc 2.95 gets confused if you don't put a space /* XXX the parser in gcc 2.95 gets confused if you don't put a space
* between the last arg before VA_ARGS and the comma */ * between the last arg before VA_ARGS and the comma */
#define manager_event(category, event, contents , ...) \ #define manager_event(category, event, contents , ...) \
__manager_event(category, event, __FILE__, __LINE__, __PRETTY_FUNCTION__, contents , ## __VA_ARGS__) __ast_manager_event_multichan(category, event, 0, NULL, __FILE__, __LINE__, __PRETTY_FUNCTION__, contents , ## __VA_ARGS__)
#define ast_manager_event(chan, category, event, contents , ...) \
do { \
struct ast_channel *_chans[] = { chan, }; \
__ast_manager_event_multichan(category, event, 1, _chans, __FILE__, __LINE__, __PRETTY_FUNCTION__, contents , ## __VA_ARGS__); \
} while (0)
#define ast_manager_event_multichan(category, event, nchans, chans, contents , ...) \
__ast_manager_event_multichan(category, event, nchans, chans, __FILE__, __LINE__, __PRETTY_FUNCTION__, contents , ## __VA_ARGS__);
int __attribute__((format(printf, 6, 7))) __manager_event(int category, const char *event, /*! External routines may send asterisk manager events this way
const char *file, int line, const char *func, * \param chan1 First channel related to this event (or NULL if none are relevant)
const char *contents, ...); * \param chan2 Second channel related to this event (or NULL if none are relevant)
* \param category Event category, matches manager authorization
* \param event Event name
* \param contents Format string describing event
* \since 1.6.3
*/
int __ast_manager_event_multichan(int category, const char *event, int chancount,
struct ast_channel **chans, const char *file, int line, const char *func,
const char *contents, ...) __attribute__((format(printf, 8, 9)));
/*! \brief Get header from mananger transaction */ /*! \brief Get header from mananger transaction */
const char *astman_get_header(const struct message *m, char *var); const char *astman_get_header(const struct message *m, char *var);

View File

@ -991,7 +991,7 @@ int ast_cdr_setaccount(struct ast_channel *chan, const char *account)
} }
} }
manager_event(EVENT_FLAG_CALL, "NewAccountCode", ast_manager_event(chan, EVENT_FLAG_CALL, "NewAccountCode",
"Channel: %s\r\n" "Channel: %s\r\n"
"Uniqueid: %s\r\n" "Uniqueid: %s\r\n"
"AccountCode: %s\r\n" "AccountCode: %s\r\n"
@ -1017,7 +1017,7 @@ int ast_cdr_setpeeraccount(struct ast_channel *chan, const char *account)
} }
} }
manager_event(EVENT_FLAG_CALL, "NewPeerAccount", ast_manager_event(chan, EVENT_FLAG_CALL, "NewPeerAccount",
"Channel: %s\r\n" "Channel: %s\r\n"
"Uniqueid: %s\r\n" "Uniqueid: %s\r\n"
"PeerAccount: %s\r\n" "PeerAccount: %s\r\n"

View File

@ -978,7 +978,7 @@ alertpipe_failed:
* a lot of data into this func to do it here! * a lot of data into this func to do it here!
*/ */
if (!ast_strlen_zero(name_fmt)) { if (!ast_strlen_zero(name_fmt)) {
manager_event(EVENT_FLAG_CALL, "Newchannel", ast_manager_event(tmp, EVENT_FLAG_CALL, "Newchannel",
"Channel: %s\r\n" "Channel: %s\r\n"
"ChannelState: %d\r\n" "ChannelState: %d\r\n"
"ChannelStateDesc: %s\r\n" "ChannelStateDesc: %s\r\n"
@ -2222,7 +2222,7 @@ int ast_hangup(struct ast_channel *chan)
} }
ast_channel_unlock(chan); ast_channel_unlock(chan);
manager_event(EVENT_FLAG_CALL, "Hangup", ast_manager_event(chan, EVENT_FLAG_CALL, "Hangup",
"Channel: %s\r\n" "Channel: %s\r\n"
"Uniqueid: %s\r\n" "Uniqueid: %s\r\n"
"CallerIDNum: %s\r\n" "CallerIDNum: %s\r\n"
@ -2974,9 +2974,9 @@ int ast_waitfordigit_full(struct ast_channel *c, int ms, int audiofd, int cmdfd)
return 0; /* Time is up */ return 0; /* Time is up */
} }
static void send_dtmf_event(const struct ast_channel *chan, const char *direction, const char digit, const char *begin, const char *end) static void send_dtmf_event(struct ast_channel *chan, const char *direction, const char digit, const char *begin, const char *end)
{ {
manager_event(EVENT_FLAG_DTMF, ast_manager_event(chan, EVENT_FLAG_DTMF,
"DTMF", "DTMF",
"Channel: %s\r\n" "Channel: %s\r\n"
"Uniqueid: %s\r\n" "Uniqueid: %s\r\n"
@ -4839,7 +4839,7 @@ retrymasq:
*/ */
static void __ast_change_name_nolink(struct ast_channel *chan, const char *newname) static void __ast_change_name_nolink(struct ast_channel *chan, const char *newname)
{ {
manager_event(EVENT_FLAG_CALL, "Rename", "Channel: %s\r\nNewname: %s\r\nUniqueid: %s\r\n", chan->name, newname, chan->uniqueid); ast_manager_event(chan, EVENT_FLAG_CALL, "Rename", "Channel: %s\r\nNewname: %s\r\nUniqueid: %s\r\n", chan->name, newname, chan->uniqueid);
ast_string_field_set(chan, name, newname); ast_string_field_set(chan, name, newname);
} }
@ -5078,9 +5078,9 @@ static void ast_set_owners_and_peers(struct ast_channel *chan1,
/*! /*!
* \pre chan is locked * \pre chan is locked
*/ */
static void report_new_callerid(const struct ast_channel *chan) static void report_new_callerid(struct ast_channel *chan)
{ {
manager_event(EVENT_FLAG_CALL, "NewCallerid", ast_manager_event(chan, EVENT_FLAG_CALL, "NewCallerid",
"Channel: %s\r\n" "Channel: %s\r\n"
"CallerIDNum: %s\r\n" "CallerIDNum: %s\r\n"
"CallerIDName: %s\r\n" "CallerIDName: %s\r\n"
@ -5116,7 +5116,7 @@ int ast_do_masquerade(struct ast_channel *original)
struct ast_party_connected_line connected; struct ast_party_connected_line connected;
struct ast_party_redirecting redirecting; struct ast_party_redirecting redirecting;
} exchange; } exchange;
struct ast_channel *clonechan; struct ast_channel *clonechan, *chans[2];
struct ast_cdr *cdr; struct ast_cdr *cdr;
format_t rformat = original->readformat; format_t rformat = original->readformat;
format_t wformat = original->writeformat; format_t wformat = original->writeformat;
@ -5180,7 +5180,9 @@ int ast_do_masquerade(struct ast_channel *original)
ast_debug(4, "Actually Masquerading %s(%d) into the structure of %s(%d)\n", ast_debug(4, "Actually Masquerading %s(%d) into the structure of %s(%d)\n",
clonechan->name, clonechan->_state, original->name, original->_state); clonechan->name, clonechan->_state, original->name, original->_state);
manager_event(EVENT_FLAG_CALL, "Masquerade", "Clone: %s\r\nCloneState: %s\r\nOriginal: %s\r\nOriginalState: %s\r\n", chans[0] = clonechan;
chans[1] = original;
ast_manager_event_multichan(EVENT_FLAG_CALL, "Masquerade", 2, chans, "Clone: %s\r\nCloneState: %s\r\nOriginal: %s\r\nOriginalState: %s\r\n",
clonechan->name, ast_state2str(clonechan->_state), original->name, ast_state2str(original->_state)); clonechan->name, ast_state2str(clonechan->_state), original->name, ast_state2str(original->_state));
/* Having remembered the original read/write formats, we turn off any translation on either /* Having remembered the original read/write formats, we turn off any translation on either
@ -5409,7 +5411,7 @@ int ast_do_masquerade(struct ast_channel *original)
if (ast_test_flag(clonechan, AST_FLAG_ZOMBIE)) { if (ast_test_flag(clonechan, AST_FLAG_ZOMBIE)) {
ast_debug(1, "Destroying channel clone '%s'\n", clonechan->name); ast_debug(1, "Destroying channel clone '%s'\n", clonechan->name);
ast_channel_unlock(clonechan); ast_channel_unlock(clonechan);
manager_event(EVENT_FLAG_CALL, "Hangup", ast_manager_event(clonechan, EVENT_FLAG_CALL, "Hangup",
"Channel: %s\r\n" "Channel: %s\r\n"
"Uniqueid: %s\r\n" "Uniqueid: %s\r\n"
"Cause: %d\r\n" "Cause: %d\r\n"
@ -5491,8 +5493,7 @@ int ast_setstate(struct ast_channel *chan, enum ast_channel_state state)
ast_devstate_changed_literal(AST_DEVICE_UNKNOWN, name); ast_devstate_changed_literal(AST_DEVICE_UNKNOWN, name);
/* setstate used to conditionally report Newchannel; this is no more */ /* setstate used to conditionally report Newchannel; this is no more */
manager_event(EVENT_FLAG_CALL, ast_manager_event(chan, EVENT_FLAG_CALL, "Newstate",
"Newstate",
"Channel: %s\r\n" "Channel: %s\r\n"
"ChannelState: %d\r\n" "ChannelState: %d\r\n"
"ChannelStateDesc: %s\r\n" "ChannelStateDesc: %s\r\n"
@ -5759,7 +5760,8 @@ int ast_channel_early_bridge(struct ast_channel *c0, struct ast_channel *c1)
*/ */
static void manager_bridge_event(int onoff, int type, struct ast_channel *c0, struct ast_channel *c1) static void manager_bridge_event(int onoff, int type, struct ast_channel *c0, struct ast_channel *c1)
{ {
manager_event(EVENT_FLAG_CALL, "Bridge", struct ast_channel *chans[2] = { c0, c1 };
ast_manager_event_multichan(EVENT_FLAG_CALL, "Bridge", 2, chans,
"Bridgestate: %s\r\n" "Bridgestate: %s\r\n"
"Bridgetype: %s\r\n" "Bridgetype: %s\r\n"
"Channel1: %s\r\n" "Channel1: %s\r\n"
@ -5843,7 +5845,7 @@ static void bridge_play_sounds(struct ast_channel *c0, struct ast_channel *c1)
enum ast_bridge_result ast_channel_bridge(struct ast_channel *c0, struct ast_channel *c1, enum ast_bridge_result ast_channel_bridge(struct ast_channel *c0, struct ast_channel *c1,
struct ast_bridge_config *config, struct ast_frame **fo, struct ast_channel **rc) struct ast_bridge_config *config, struct ast_frame **fo, struct ast_channel **rc)
{ {
struct ast_channel *who = NULL; struct ast_channel *who = NULL, *chans[2] = { c0, c1 };
enum ast_bridge_result res = AST_BRIDGE_COMPLETE; enum ast_bridge_result res = AST_BRIDGE_COMPLETE;
int nativefailed=0; int nativefailed=0;
format_t o0nativeformats; format_t o0nativeformats;
@ -6017,7 +6019,7 @@ enum ast_bridge_result ast_channel_bridge(struct ast_channel *c0, struct ast_cha
ast_set_flag(c0, AST_FLAG_NBRIDGE); ast_set_flag(c0, AST_FLAG_NBRIDGE);
ast_set_flag(c1, AST_FLAG_NBRIDGE); ast_set_flag(c1, AST_FLAG_NBRIDGE);
if ((res = c0->tech->bridge(c0, c1, config->flags, fo, rc, to)) == AST_BRIDGE_COMPLETE) { if ((res = c0->tech->bridge(c0, c1, config->flags, fo, rc, to)) == AST_BRIDGE_COMPLETE) {
manager_event(EVENT_FLAG_CALL, "Unlink", ast_manager_event_multichan(EVENT_FLAG_CALL, "Unlink", 2, chans,
"Channel1: %s\r\n" "Channel1: %s\r\n"
"Channel2: %s\r\n" "Channel2: %s\r\n"
"Uniqueid1: %s\r\n" "Uniqueid1: %s\r\n"
@ -6089,7 +6091,7 @@ enum ast_bridge_result ast_channel_bridge(struct ast_channel *c0, struct ast_cha
c0->_bridge = NULL; c0->_bridge = NULL;
c1->_bridge = NULL; c1->_bridge = NULL;
manager_event(EVENT_FLAG_CALL, "Unlink", ast_manager_event_multichan(EVENT_FLAG_CALL, "Unlink", 2, chans,
"Channel1: %s\r\n" "Channel1: %s\r\n"
"Channel2: %s\r\n" "Channel2: %s\r\n"
"Uniqueid1: %s\r\n" "Uniqueid1: %s\r\n"

View File

@ -890,7 +890,7 @@ static int park_call_full(struct ast_channel *chan, struct ast_channel *peer, st
event_from = pbx_builtin_getvar_helper(chan, "BLINDTRANSFER"); event_from = pbx_builtin_getvar_helper(chan, "BLINDTRANSFER");
} }
manager_event(EVENT_FLAG_CALL, "ParkedCall", ast_manager_event(pu->chan, EVENT_FLAG_CALL, "ParkedCall",
"Exten: %s\r\n" "Exten: %s\r\n"
"Channel: %s\r\n" "Channel: %s\r\n"
"Parkinglot: %s\r\n" "Parkinglot: %s\r\n"
@ -3641,7 +3641,7 @@ static int park_exec_full(struct ast_channel *chan, const char *data, struct ast
ast_log(LOG_WARNING, "Whoa, no parking context?\n"); ast_log(LOG_WARNING, "Whoa, no parking context?\n");
ast_cel_report_event(pu->chan, AST_CEL_PARK_END, NULL, "UnParkedCall", chan); ast_cel_report_event(pu->chan, AST_CEL_PARK_END, NULL, "UnParkedCall", chan);
manager_event(EVENT_FLAG_CALL, "UnParkedCall", ast_manager_event(pu->chan, EVENT_FLAG_CALL, "UnParkedCall",
"Exten: %s\r\n" "Exten: %s\r\n"
"Channel: %s\r\n" "Channel: %s\r\n"
"From: %s\r\n" "From: %s\r\n"
@ -4944,7 +4944,7 @@ int ast_bridge_timelimit(struct ast_channel *chan, struct ast_bridge_config *con
*/ */
static int bridge_exec(struct ast_channel *chan, const char *data) static int bridge_exec(struct ast_channel *chan, const char *data)
{ {
struct ast_channel *current_dest_chan, *final_dest_chan; struct ast_channel *current_dest_chan, *final_dest_chan, *chans[2];
char *tmp_data = NULL; char *tmp_data = NULL;
struct ast_flags opts = { 0, }; struct ast_flags opts = { 0, };
struct ast_bridge_config bconfig = { { 0, }, }; struct ast_bridge_config bconfig = { { 0, }, };
@ -4971,7 +4971,7 @@ static int bridge_exec(struct ast_channel *chan, const char *data)
strlen(chan->name) < strlen(args.dest_chan) ? strlen(chan->name) < strlen(args.dest_chan) ?
strlen(chan->name) : strlen(args.dest_chan))) { strlen(chan->name) : strlen(args.dest_chan))) {
ast_log(LOG_WARNING, "Unable to bridge channel %s with itself\n", chan->name); ast_log(LOG_WARNING, "Unable to bridge channel %s with itself\n", chan->name);
manager_event(EVENT_FLAG_CALL, "BridgeExec", ast_manager_event(chan, EVENT_FLAG_CALL, "BridgeExec",
"Response: Failed\r\n" "Response: Failed\r\n"
"Reason: Unable to bridge channel to itself\r\n" "Reason: Unable to bridge channel to itself\r\n"
"Channel1: %s\r\n" "Channel1: %s\r\n"
@ -4986,7 +4986,7 @@ static int bridge_exec(struct ast_channel *chan, const char *data)
strlen(args.dest_chan)))) { strlen(args.dest_chan)))) {
ast_log(LOG_WARNING, "Bridge failed because channel %s does not exists or we " ast_log(LOG_WARNING, "Bridge failed because channel %s does not exists or we "
"cannot get its lock\n", args.dest_chan); "cannot get its lock\n", args.dest_chan);
manager_event(EVENT_FLAG_CALL, "BridgeExec", ast_manager_event(chan, EVENT_FLAG_CALL, "BridgeExec",
"Response: Failed\r\n" "Response: Failed\r\n"
"Reason: Cannot grab end point\r\n" "Reason: Cannot grab end point\r\n"
"Channel1: %s\r\n" "Channel1: %s\r\n"
@ -5004,7 +5004,7 @@ static int bridge_exec(struct ast_channel *chan, const char *data)
if (!(final_dest_chan = ast_channel_alloc(0, AST_STATE_DOWN, NULL, NULL, NULL, if (!(final_dest_chan = ast_channel_alloc(0, AST_STATE_DOWN, NULL, NULL, NULL,
NULL, NULL, current_dest_chan->linkedid, 0, "Bridge/%s", current_dest_chan->name))) { NULL, NULL, current_dest_chan->linkedid, 0, "Bridge/%s", current_dest_chan->name))) {
ast_log(LOG_WARNING, "Cannot create placeholder channel for chan %s\n", args.dest_chan); ast_log(LOG_WARNING, "Cannot create placeholder channel for chan %s\n", args.dest_chan);
manager_event(EVENT_FLAG_CALL, "BridgeExec", ast_manager_event(chan, EVENT_FLAG_CALL, "BridgeExec",
"Response: Failed\r\n" "Response: Failed\r\n"
"Reason: cannot create placeholder\r\n" "Reason: cannot create placeholder\r\n"
"Channel1: %s\r\n" "Channel1: %s\r\n"
@ -5015,11 +5015,14 @@ static int bridge_exec(struct ast_channel *chan, const char *data)
do_bridge_masquerade(current_dest_chan, final_dest_chan); do_bridge_masquerade(current_dest_chan, final_dest_chan);
chans[0] = current_dest_chan;
chans[1] = final_dest_chan;
/* now current_dest_chan is a ZOMBIE and with softhangup set to 1 and final_dest_chan is our end point */ /* now current_dest_chan is a ZOMBIE and with softhangup set to 1 and final_dest_chan is our end point */
/* try to make compatible, send error if we fail */ /* try to make compatible, send error if we fail */
if (ast_channel_make_compatible(chan, final_dest_chan) < 0) { if (ast_channel_make_compatible(chan, final_dest_chan) < 0) {
ast_log(LOG_WARNING, "Could not make channels %s and %s compatible for bridge\n", chan->name, final_dest_chan->name); ast_log(LOG_WARNING, "Could not make channels %s and %s compatible for bridge\n", chan->name, final_dest_chan->name);
manager_event(EVENT_FLAG_CALL, "BridgeExec", ast_manager_event_multichan(EVENT_FLAG_CALL, "BridgeExec", 2, chans,
"Response: Failed\r\n" "Response: Failed\r\n"
"Reason: Could not make channels compatible for bridge\r\n" "Reason: Could not make channels compatible for bridge\r\n"
"Channel1: %s\r\n" "Channel1: %s\r\n"
@ -5031,7 +5034,7 @@ static int bridge_exec(struct ast_channel *chan, const char *data)
} }
/* Report that the bridge will be successfull */ /* Report that the bridge will be successfull */
manager_event(EVENT_FLAG_CALL, "BridgeExec", ast_manager_event_multichan(EVENT_FLAG_CALL, "BridgeExec", 2, chans,
"Response: Success\r\n" "Response: Success\r\n"
"Channel1: %s\r\n" "Channel1: %s\r\n"
"Channel2: %s\r\n", chan->name, final_dest_chan->name); "Channel2: %s\r\n", chan->name, final_dest_chan->name);

View File

@ -844,6 +844,14 @@ struct mansession {
static struct ao2_container *sessions = NULL; static struct ao2_container *sessions = NULL;
struct manager_channel_variable {
AST_LIST_ENTRY(manager_channel_variable) entry;
unsigned int isfunc:1;
char name[0]; /* allocate off the end the real size. */
};
static AST_RWLIST_HEAD_STATIC(channelvars, manager_channel_variable);
#define NEW_EVENT(m) (AST_LIST_NEXT(m->session->last_ev, eq_next)) #define NEW_EVENT(m) (AST_LIST_NEXT(m->session->last_ev, eq_next))
/*! \brief user descriptor, as read from the config file. /*! \brief user descriptor, as read from the config file.
@ -876,6 +884,7 @@ static AST_RWLIST_HEAD_STATIC(manager_hooks, manager_custom_hook);
static struct eventqent *unref_event(struct eventqent *e); static struct eventqent *unref_event(struct eventqent *e);
static void ref_event(struct eventqent *e); static void ref_event(struct eventqent *e);
static void free_channelvars(void);
/*! \brief Add a custom hook to be called when an event is fired */ /*! \brief Add a custom hook to be called when an event is fired */
void ast_manager_register_hook(struct manager_custom_hook *hook) void ast_manager_register_hook(struct manager_custom_hook *hook)
@ -3292,7 +3301,7 @@ static void *fast_originate(void *data)
struct fast_originate_helper *in = data; struct fast_originate_helper *in = data;
int res; int res;
int reason = 0; int reason = 0;
struct ast_channel *chan = NULL; struct ast_channel *chan = NULL, *chans[1];
char requested_channel[AST_CHANNEL_NAME]; char requested_channel[AST_CHANNEL_NAME];
if (!ast_strlen_zero(in->app)) { if (!ast_strlen_zero(in->app)) {
@ -3311,7 +3320,8 @@ static void *fast_originate(void *data)
snprintf(requested_channel, AST_CHANNEL_NAME, "%s/%s", in->tech, in->data); snprintf(requested_channel, AST_CHANNEL_NAME, "%s/%s", in->tech, in->data);
} }
/* Tell the manager what happened with the channel */ /* Tell the manager what happened with the channel */
manager_event(EVENT_FLAG_CALL, "OriginateResponse", chans[0] = chan;
ast_manager_event_multichan(EVENT_FLAG_CALL, "OriginateResponse", chan ? 1 : 0, chans,
"%s%s" "%s%s"
"Response: %s\r\n" "Response: %s\r\n"
"Channel: %s\r\n" "Channel: %s\r\n"
@ -4211,13 +4221,34 @@ static int append_event(const char *str, int category)
return 0; return 0;
} }
AST_THREADSTORAGE(manager_event_funcbuf);
static void append_channel_vars(struct ast_str **pbuf, struct ast_channel *chan)
{
struct manager_channel_variable *var;
AST_RWLIST_RDLOCK(&channelvars);
AST_LIST_TRAVERSE(&channelvars, var, entry) {
const char *val = "";
if (var->isfunc) {
struct ast_str *res = ast_str_thread_get(&manager_event_funcbuf, 16);
int ret;
if (res && (ret = ast_func_read2(chan, var->name, &res, 0)) == 0) {
val = ast_str_buffer(res);
}
} else {
val = pbx_builtin_getvar_helper(chan, var->name);
}
ast_str_append(pbuf, 0, "ChanVariable(%s): %s=%s\r\n", chan->name, var->name, val ? val : "");
}
AST_RWLIST_UNLOCK(&channelvars);
}
/* XXX see if can be moved inside the function */ /* XXX see if can be moved inside the function */
AST_THREADSTORAGE(manager_event_buf); AST_THREADSTORAGE(manager_event_buf);
#define MANAGER_EVENT_BUF_INITSIZE 256 #define MANAGER_EVENT_BUF_INITSIZE 256
/*! \brief manager_event: Send AMI event to client */ int __ast_manager_event_multichan(int category, const char *event, int chancount, struct
int __manager_event(int category, const char *event, ast_channel **chans, const char *file, int line, const char *func, const char *fmt, ...)
const char *file, int line, const char *func, const char *fmt, ...)
{ {
struct mansession_session *session; struct mansession_session *session;
struct manager_custom_hook *hook; struct manager_custom_hook *hook;
@ -4226,6 +4257,7 @@ int __manager_event(int category, const char *event,
va_list ap; va_list ap;
struct timeval now; struct timeval now;
struct ast_str *buf; struct ast_str *buf;
int i;
if (!(buf = ast_str_thread_get(&manager_event_buf, MANAGER_EVENT_BUF_INITSIZE))) { if (!(buf = ast_str_thread_get(&manager_event_buf, MANAGER_EVENT_BUF_INITSIZE))) {
return -1; return -1;
@ -4254,6 +4286,9 @@ int __manager_event(int category, const char *event,
va_start(ap, fmt); va_start(ap, fmt);
ast_str_append_va(&buf, 0, fmt, ap); ast_str_append_va(&buf, 0, fmt, ap);
va_end(ap); va_end(ap);
for (i = 0; i < chancount; i++) {
append_channel_vars(&buf, chans[i]);
}
ast_str_append(&buf, 0, "\r\n"); ast_str_append(&buf, 0, "\r\n");
@ -5559,6 +5594,8 @@ static int __init_manager(int reload)
} }
ami_tls_cfg.cipher = ast_strdup(""); ami_tls_cfg.cipher = ast_strdup("");
free_channelvars();
for (var = ast_variable_browse(cfg, "general"); var; var = var->next) { for (var = ast_variable_browse(cfg, "general"); var; var = var->next) {
val = var->value; val = var->value;
@ -5589,6 +5626,21 @@ static int __init_manager(int reload)
manager_debug = ast_true(val); manager_debug = ast_true(val);
} else if (!strcasecmp(var->name, "httptimeout")) { } else if (!strcasecmp(var->name, "httptimeout")) {
newhttptimeout = atoi(val); newhttptimeout = atoi(val);
} else if (!strcasecmp(var->name, "channelvars")) {
struct manager_channel_variable *mcv;
char *remaining = ast_strdupa(val), *next;
AST_RWLIST_WRLOCK(&channelvars);
while ((next = strsep(&remaining, ",|"))) {
if (!(mcv = ast_calloc(1, sizeof(*mcv) + strlen(next) + 1))) {
break;
}
strcpy(mcv->name, next); /* SAFE */
if (strchr(next, '(')) {
mcv->isfunc = 1;
}
AST_RWLIST_INSERT_TAIL(&channelvars, mcv, entry);
}
AST_RWLIST_UNLOCK(&channelvars);
} else { } else {
ast_log(LOG_NOTICE, "Invalid keyword <%s> = <%s> in manager.conf [general]\n", ast_log(LOG_NOTICE, "Invalid keyword <%s> = <%s> in manager.conf [general]\n",
var->name, val); var->name, val);
@ -5830,6 +5882,17 @@ static int __init_manager(int reload)
return 0; return 0;
} }
/* clear out every entry in the channelvar list */
static void free_channelvars(void)
{
struct manager_channel_variable *var;
AST_RWLIST_WRLOCK(&channelvars);
while ((var = AST_RWLIST_REMOVE_HEAD(&channelvars, entry))) {
ast_free(var);
}
AST_RWLIST_UNLOCK(&channelvars);
}
int init_manager(void) int init_manager(void)
{ {
return __init_manager(0); return __init_manager(0);

View File

@ -382,12 +382,11 @@ int AST_OPTIONAL_API_NAME(ast_monitor_start)(struct ast_channel *chan, const cha
/* so we know this call has been monitored in case we need to bill for it or something */ /* so we know this call has been monitored in case we need to bill for it or something */
pbx_builtin_setvar_helper(chan, "__MONITORED","true"); pbx_builtin_setvar_helper(chan, "__MONITORED","true");
manager_event(EVENT_FLAG_CALL, "MonitorStart", ast_manager_event(chan, EVENT_FLAG_CALL, "MonitorStart",
"Channel: %s\r\n" "Channel: %s\r\n"
"Uniqueid: %s\r\n", "Uniqueid: %s\r\n",
chan->name, chan->name,
chan->uniqueid chan->uniqueid);
);
} else { } else {
ast_debug(1,"Cannot start monitoring %s, already monitored\n", chan->name); ast_debug(1,"Cannot start monitoring %s, already monitored\n", chan->name);
res = -1; res = -1;
@ -502,7 +501,7 @@ int AST_OPTIONAL_API_NAME(ast_monitor_stop)(struct ast_channel *chan, int need_l
ast_free(chan->monitor); ast_free(chan->monitor);
chan->monitor = NULL; chan->monitor = NULL;
manager_event(EVENT_FLAG_CALL, "MonitorStop", ast_manager_event(chan, EVENT_FLAG_CALL, "MonitorStop",
"Channel: %s\r\n" "Channel: %s\r\n"
"Uniqueid: %s\r\n", "Uniqueid: %s\r\n",
chan->name, chan->name,

View File

@ -1346,7 +1346,7 @@ static int local_ast_moh_start(struct ast_channel *chan, const char *mclass, con
return -1; return -1;
} }
manager_event(EVENT_FLAG_CALL, "MusicOnHold", ast_manager_event(chan, EVENT_FLAG_CALL, "MusicOnHold",
"State: Start\r\n" "State: Start\r\n"
"Channel: %s\r\n" "Channel: %s\r\n"
"UniqueID: %s\r\n", "UniqueID: %s\r\n",
@ -1378,7 +1378,7 @@ static void local_ast_moh_stop(struct ast_channel *chan)
} }
} }
manager_event(EVENT_FLAG_CALL, "MusicOnHold", ast_manager_event(chan, EVENT_FLAG_CALL, "MusicOnHold",
"State: Stop\r\n" "State: Stop\r\n"
"Channel: %s\r\n" "Channel: %s\r\n"
"UniqueID: %s\r\n", "UniqueID: %s\r\n",