summaryrefslogtreecommitdiff
path: root/channels/chan_sip.c
diff options
context:
space:
mode:
authorKevin P. Fleming <kpfleming@digium.com>2005-07-25 17:39:48 +0000
committerKevin P. Fleming <kpfleming@digium.com>2005-07-25 17:39:48 +0000
commit1153f74259887b857361ec5bb3c6b21cd01342f7 (patch)
treed69545079ab4f7a66af6347bf9499fcdc8da8269 /channels/chan_sip.c
parenteeb34ffd63ed06ae613bd6cb94f90cdb3adabd98 (diff)
add plain-text hangup cause private header to outbound BYE/CANCEL (bug #4783 with minor mods)
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@6192 65c4cc65-6c06-0410-ace0-fbb531ad65f3
Diffstat (limited to 'channels/chan_sip.c')
-rwxr-xr-xchannels/chan_sip.c56
1 files changed, 36 insertions, 20 deletions
diff --git a/channels/chan_sip.c b/channels/chan_sip.c
index 20f198f12..61d958af8 100755
--- a/channels/chan_sip.c
+++ b/channels/chan_sip.c
@@ -164,9 +164,9 @@ const struct cfsip_methods {
};
/* Structure for conversion between compressed SIP and "normal" SIP */
-static struct cfalias {
- char *fullname;
- char *shortname;
+static const struct cfalias {
+ char * const fullname;
+ char * const shortname;
} aliases[] = {
{ "Content-Type", "c" },
{ "Content-Encoding", "e" },
@@ -2185,12 +2185,13 @@ static int sip_hangup(struct ast_channel *ast)
int needcancel = 0;
struct ast_flags locflags = {0};
- if (option_debug)
- ast_log(LOG_DEBUG, "sip_hangup(%s)\n", ast->name);
if (!p) {
ast_log(LOG_DEBUG, "Asked to hangup channel not connected\n");
return 0;
}
+ if (option_debug)
+ ast_log(LOG_DEBUG, "Hangup call %s, SIP callid %s)\n", ast->name, p->callid);
+
ast_mutex_lock(&p->lock);
#ifdef OSP_SUPPORT
if ((p->osphandle > -1) && (ast->_state == AST_STATE_UP)) {
@@ -2206,12 +2207,14 @@ static int sip_hangup(struct ast_channel *ast)
}
/* Determine how to disconnect */
if (p->owner != ast) {
- ast_log(LOG_WARNING, "Huh? We aren't the owner?\n");
+ ast_log(LOG_WARNING, "Huh? We aren't the owner? Can't hangup call.\n");
ast_mutex_unlock(&p->lock);
return 0;
}
+ /* If the call is not UP, we need to send CANCEL instead of BYE */
if (ast->_state != AST_STATE_UP)
needcancel = 1;
+
/* Disconnect */
p = ast->tech_pvt;
if (p->vad) {
@@ -2226,9 +2229,10 @@ static int sip_hangup(struct ast_channel *ast)
ast_update_use_count();
ast_set_flag(&locflags, SIP_NEEDDESTROY);
+
/* Start the process if it's not already started */
if (!ast_test_flag(p, SIP_ALREADYGONE) && !ast_strlen_zero(p->initreq.data)) {
- if (needcancel) {
+ if (needcancel) { /* Outgoing call, not up */
if (ast_test_flag(p, SIP_OUTGOING)) {
transmit_request_with_auth(p, SIP_CANCEL, p->ocseq, 1, 0);
/* Actually don't destroy us yet, wait for the 487 on our original
@@ -2245,14 +2249,14 @@ static int sip_hangup(struct ast_channel *ast)
update_user_counter(p, INC_IN_USE);
}
}
- } else {
+ } else { /* Incoming call, not up */
char *res;
if (ast->hangupcause && ((res = hangup_cause2sip(ast->hangupcause)))) {
transmit_response_reliable(p, res, &p->initreq, 1);
} else
transmit_response_reliable(p, "403 Forbidden", &p->initreq, 1);
}
- } else {
+ } else { /* Call is in UP state, send BYE */
if (!p->pendinginvite) {
/* Send a hangup */
transmit_request_with_auth(p, SIP_BYE, 0, 1, 1);
@@ -3392,36 +3396,37 @@ static int process_sdp(struct sip_pvt *p, struct sip_request *req)
}
/*--- add_header: Add header to SIP message */
-static int add_header(struct sip_request *req, char *var, char *value)
+static int add_header(struct sip_request *req, const char *var, const char *value)
{
int x = 0;
- char *shortname = "";
+
if (req->headers == SIP_MAX_HEADERS) {
ast_log(LOG_WARNING, "Out of SIP header space\n");
return -1;
}
+
if (req->lines) {
ast_log(LOG_WARNING, "Can't add more headers when lines have been added\n");
return -1;
}
+
if (req->len >= sizeof(req->data) - 4) {
ast_log(LOG_WARNING, "Out of space, can't add anymore (%s:%s)\n", var, value);
return -1;
}
req->header[req->headers] = req->data + req->len;
+
if (compactheaders) {
- for (x=0;x<sizeof(aliases) / sizeof(aliases[0]); x++)
+ for (x = 0; x < (sizeof(aliases) / sizeof(aliases[0])); x++)
if (!strcasecmp(aliases[x].fullname, var))
- shortname = aliases[x].shortname;
- }
- if (!ast_strlen_zero(shortname)) {
- snprintf(req->header[req->headers], sizeof(req->data) - req->len - 4, "%s: %s\r\n", shortname, value);
- } else {
- snprintf(req->header[req->headers], sizeof(req->data) - req->len - 4, "%s: %s\r\n", var, value);
+ var = aliases[x].shortname;
}
+
+ snprintf(req->header[req->headers], sizeof(req->data) - req->len - 4, "%s: %s\r\n", var, value);
req->len += strlen(req->header[req->headers]);
req->headers++;
+
return 0;
}
@@ -3811,6 +3816,11 @@ static int __transmit_response(struct sip_pvt *p, char *msg, struct sip_request
}
respprep(&resp, p, msg, req);
add_header(&resp, "Content-Length", "0");
+ /* If we are cancelling an incoming invite for some reason, add information
+ about the reason why we are doing this in clear text */
+ if (p->owner && p->owner->hangupcause) {
+ add_header(&resp, "X-Asterisk-HangupCause:", ast_cause2str(p->owner->hangupcause));
+ }
add_blank_header(&resp);
return send_response(p, &resp, reliable, seqno);
}
@@ -5012,14 +5022,20 @@ static int transmit_request_with_auth(struct sip_pvt *p, int sipmethod, int seqn
struct sip_request resp;
reqprep(&resp, p, sipmethod, seqno, newbranch);
- if (*p->realm)
- {
+ if (*p->realm) {
char digest[1024];
memset(digest, 0, sizeof(digest));
build_reply_digest(p, sipmethod, digest, sizeof(digest));
add_header(&resp, "Proxy-Authorization", digest);
}
+ /* If we are hanging up and know a cause for that, send it in clear text to make
+ debugging easier. */
+ if (sipmethod == SIP_BYE) {
+ if (p->owner && p->owner->hangupcause) {
+ add_header(&resp, "X-Asterisk-HangupCause:", ast_cause2str(p->owner->hangupcause));
+ }
+ }
add_header(&resp, "Content-Length", "0");
add_blank_header(&resp);