summaryrefslogtreecommitdiff
path: root/channels/chan_sip.c
diff options
context:
space:
mode:
authorRussell Bryant <russell@russellbryant.com>2009-06-26 15:28:53 +0000
committerRussell Bryant <russell@russellbryant.com>2009-06-26 15:28:53 +0000
commit0264eef1156b8ef7369884dd5c663646f1b2b429 (patch)
treea28e9113cf1daf97e45a8fc6d41a52c76ac69836 /channels/chan_sip.c
parente06c6f97c4c222b4c802ac2b85f76a331991dffb (diff)
Merge the new Channel Event Logging (CEL) subsystem.
CEL is the new system for logging channel events. This was inspired after facing many problems trying to represent what is possible to happen to a call in Asterisk using CDR records. For more information on CEL, see the built in HTML or PDF documentation generated from the files in doc/tex/. Many thanks to Steve Murphy (murf) and Brian Degenhardt (bmd) for their hard work developing this code. Also, thanks to Matt Nicholson (mnicholson) and Sean Bright (seanbright) for their assistance in the final push to get this code ready for Asterisk trunk. Review: https://reviewboard.asterisk.org/r/239/ git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@203638 65c4cc65-6c06-0410-ace0-fbb531ad65f3
Diffstat (limited to 'channels/chan_sip.c')
-rw-r--r--channels/chan_sip.c55
1 files changed, 43 insertions, 12 deletions
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",