mirror of
https://github.com/asterisk/asterisk.git
synced 2026-07-28 00:10:25 -07:00
Commit framework for HANGUPCAUSE (replacement for SIP_CAUSE)
This is the starting point for the Asterisk 11: Who Hung Up work and provides a framework which will allow channel drivers to report the types of hangup cause information available in SIP_CAUSE without incurring the overhead of the MASTER_CHANNEL dialplan function. The initial implementation only includes cause generation for chan_sip and does not include cause code translation utilities. This change deprecates SIP_CAUSE and replaces its method of reporting cause codes with the new framework. This change also deprecates the 'storesipcause' option in sip.conf. Review: https://reviewboard.asterisk.org/r/1822/ (Closes issue SWP-4221) git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@366408 65c4cc65-6c06-0410-ace0-fbb531ad65f3
This commit is contained in:
@@ -91,6 +91,11 @@ SIP
|
||||
- A new manager event, "SessionTimeout" has been added and is triggered when
|
||||
a call is terminated due to RTP stream inactivity or SIP session timer
|
||||
expiration.
|
||||
- SIP_CAUSE is now deprecated. It has been modified to use the same
|
||||
mechanism as HANGUPCAUSE. Behavior should not change, but performance
|
||||
should be vastly improved. The HANGUPCAUSE hash should now be used instead
|
||||
of SIP_CAUSE. Because of this, the storesipcause option in sip.conf is also
|
||||
deprecated.
|
||||
|
||||
chan_unistim
|
||||
- Due to massive update in chan_unistim phone keys functions and on-screen
|
||||
|
||||
@@ -1427,6 +1427,9 @@ static struct ast_channel *wait_for_answer(struct ast_channel *in,
|
||||
cc_frame_received = 1;
|
||||
}
|
||||
break;
|
||||
case AST_CONTROL_PVT_CAUSE_CODE:
|
||||
ast_indicate_data(in, AST_CONTROL_PVT_CAUSE_CODE, f->data.ptr, f->datalen);
|
||||
break;
|
||||
case -1:
|
||||
if (single && !caller_entertained) {
|
||||
ast_verb(3, "%s stopped sounds\n", ast_channel_name(c));
|
||||
|
||||
@@ -877,6 +877,9 @@ static struct ast_channel *wait_for_winner(struct findme_user_listptr *findme_us
|
||||
* the caller.
|
||||
*/
|
||||
break;
|
||||
case AST_CONTROL_PVT_CAUSE_CODE:
|
||||
ast_indicate_data(caller, f->subclass.integer, f->data.ptr, f->datalen);
|
||||
break;
|
||||
case -1:
|
||||
ast_verb(3, "%s stopped sounds\n", ast_channel_name(winner));
|
||||
break;
|
||||
|
||||
@@ -4050,6 +4050,9 @@ static struct callattempt *wait_for_answer(struct queue_ent *qe, struct callatte
|
||||
}
|
||||
}
|
||||
break;
|
||||
case AST_CONTROL_PVT_CAUSE_CODE:
|
||||
ast_indicate_data(in, AST_CONTROL_PVT_CAUSE_CODE, f->data.ptr, f->datalen);
|
||||
break;
|
||||
default:
|
||||
ast_debug(1, "Dunno what to do with control type %d\n", f->subclass.integer);
|
||||
break;
|
||||
|
||||
@@ -534,6 +534,7 @@ static int alsa_indicate(struct ast_channel *chan, int cond, const void *data, s
|
||||
case AST_CONTROL_CONGESTION:
|
||||
case AST_CONTROL_RINGING:
|
||||
case AST_CONTROL_INCOMPLETE:
|
||||
case AST_CONTROL_PVT_CAUSE_CODE:
|
||||
case -1:
|
||||
res = -1; /* Ask for inband indications */
|
||||
break;
|
||||
|
||||
@@ -603,6 +603,7 @@ static int console_indicate(struct ast_channel *chan, int cond, const void *data
|
||||
case AST_CONTROL_CONGESTION:
|
||||
case AST_CONTROL_RINGING:
|
||||
case AST_CONTROL_INCOMPLETE:
|
||||
case AST_CONTROL_PVT_CAUSE_CODE:
|
||||
case -1:
|
||||
res = -1; /* Ask for inband indications */
|
||||
break;
|
||||
|
||||
@@ -1726,6 +1726,8 @@ static int gtalk_indicate(struct ast_channel *ast, int condition, const void *da
|
||||
break;
|
||||
default:
|
||||
ast_debug(3, "Don't know how to indicate condition '%d'\n", condition);
|
||||
/* fallthrough */
|
||||
case AST_CONTROL_PVT_CAUSE_CODE:
|
||||
res = -1;
|
||||
}
|
||||
|
||||
|
||||
@@ -941,6 +941,7 @@ static int oh323_indicate(struct ast_channel *c, int condition, const void *data
|
||||
res = 0;
|
||||
break;
|
||||
case AST_CONTROL_PROCEEDING:
|
||||
case AST_CONTROL_PVT_CAUSE_CODE:
|
||||
case -1:
|
||||
break;
|
||||
default:
|
||||
|
||||
@@ -5669,6 +5669,9 @@ static int iax2_indicate(struct ast_channel *c, int condition, const void *data,
|
||||
if (!ast_test_flag64(pvt, IAX_SENDCONNECTEDLINE))
|
||||
goto done;
|
||||
break;
|
||||
case AST_CONTROL_PVT_CAUSE_CODE:
|
||||
res = -1;
|
||||
break;
|
||||
}
|
||||
|
||||
res = send_command(pvt, AST_FRAME_CONTROL, condition, 0, data, datalen, -1);
|
||||
|
||||
@@ -1332,6 +1332,8 @@ static int jingle_indicate(struct ast_channel *ast, int condition, const void *d
|
||||
break;
|
||||
default:
|
||||
ast_log(LOG_NOTICE, "Don't know how to indicate condition '%d'\n", condition);
|
||||
/* fallthrough */
|
||||
case AST_CONTROL_PVT_CAUSE_CODE:
|
||||
res = -1;
|
||||
}
|
||||
|
||||
|
||||
@@ -1483,6 +1483,8 @@ static int mgcp_indicate(struct ast_channel *ast, int ind, const void *data, siz
|
||||
break;
|
||||
default:
|
||||
ast_log(LOG_WARNING, "Don't know how to indicate condition %d\n", ind);
|
||||
/* fallthrough */
|
||||
case AST_CONTROL_PVT_CAUSE_CODE:
|
||||
res = -1;
|
||||
}
|
||||
ast_mutex_unlock(&sub->lock);
|
||||
|
||||
@@ -7037,6 +7037,8 @@ static int misdn_indication(struct ast_channel *ast, int cond, const void *data,
|
||||
break;
|
||||
default:
|
||||
chan_misdn_log(1, p->bc->port, " --> * Unknown Indication:%d pid:%d\n", cond, p->bc->pid);
|
||||
/* fallthrough */
|
||||
case AST_CONTROL_PVT_CAUSE_CODE:
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
@@ -758,6 +758,7 @@ static int oss_indicate(struct ast_channel *c, int cond, const void *data, size_
|
||||
case AST_CONTROL_BUSY:
|
||||
case AST_CONTROL_CONGESTION:
|
||||
case AST_CONTROL_RINGING:
|
||||
case AST_CONTROL_PVT_CAUSE_CODE:
|
||||
case -1:
|
||||
res = -1;
|
||||
break;
|
||||
|
||||
@@ -222,6 +222,8 @@ static int phone_indicate(struct ast_channel *chan, int condition, const void *d
|
||||
case AST_CONTROL_SRCUPDATE:
|
||||
res = 0;
|
||||
break;
|
||||
case AST_CONTROL_PVT_CAUSE_CODE:
|
||||
break;
|
||||
default:
|
||||
ast_log(LOG_WARNING, "Condition %d is not supported on channel %s\n", condition, ast_channel_name(chan));
|
||||
}
|
||||
|
||||
+19
-14
@@ -7093,6 +7093,7 @@ static int sip_indicate(struct ast_channel *ast, int condition, const void *data
|
||||
break;
|
||||
case AST_CONTROL_UPDATE_RTP_PEER: /* Absorb this since it is handled by the bridge */
|
||||
break;
|
||||
case AST_CONTROL_PVT_CAUSE_CODE: /* these should be handled by the code in channel.c */
|
||||
case -1:
|
||||
res = -1;
|
||||
break;
|
||||
@@ -26113,28 +26114,29 @@ static int handle_incoming(struct sip_pvt *p, struct sip_request *req, struct as
|
||||
ast_debug(1, "Ignoring out of order response %u (expecting %u)\n", seqno, p->ocseq);
|
||||
return -1;
|
||||
} else {
|
||||
char causevar[256], causeval[256];
|
||||
|
||||
if ((respid == 200) || ((respid >= 300) && (respid <= 399))) {
|
||||
extract_uri(p, req);
|
||||
}
|
||||
|
||||
handle_response(p, respid, e + len, req, seqno);
|
||||
if (p->owner) {
|
||||
struct ast_control_pvt_cause_code *cause_code;
|
||||
int data_size = sizeof(*cause_code);
|
||||
/* size of the string making up the cause code is "SIP " + cause length */
|
||||
data_size += 4 + strlen(REQ_OFFSET_TO_STR(req, rlPart2));
|
||||
cause_code = alloca(data_size);
|
||||
|
||||
if (global_store_sip_cause && p->owner) {
|
||||
struct ast_channel *owner = p->owner;
|
||||
ast_copy_string(cause_code->chan_name, ast_channel_name(p->owner), AST_CHANNEL_NAME);
|
||||
|
||||
snprintf(causevar, sizeof(causevar), "MASTER_CHANNEL(HASH(SIP_CAUSE,%s))", ast_channel_name(owner));
|
||||
snprintf(causeval, sizeof(causeval), "SIP %s", REQ_OFFSET_TO_STR(req, rlPart2));
|
||||
snprintf(cause_code->code, data_size - sizeof(*cause_code) + 1, "SIP %s", REQ_OFFSET_TO_STR(req, rlPart2));
|
||||
|
||||
ast_channel_ref(owner);
|
||||
sip_pvt_unlock(p);
|
||||
ast_channel_unlock(owner);
|
||||
*nounlock = 1;
|
||||
pbx_builtin_setvar_helper(owner, causevar, causeval);
|
||||
ast_channel_unref(owner);
|
||||
sip_pvt_lock(p);
|
||||
if (global_store_sip_cause) {
|
||||
cause_code->emulate_sip_cause = 1;
|
||||
}
|
||||
|
||||
ast_queue_control_data(p->owner, AST_CONTROL_PVT_CAUSE_CODE, cause_code, data_size);
|
||||
}
|
||||
|
||||
handle_response(p, respid, e + len, req, seqno);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
@@ -29882,6 +29884,9 @@ static int reload_config(enum channelreloadreason reason)
|
||||
}
|
||||
} else if (!strcasecmp(v->name, "storesipcause")) {
|
||||
global_store_sip_cause = ast_true(v->value);
|
||||
if (global_store_sip_cause) {
|
||||
ast_log(LOG_WARNING, "Usage of SIP_CAUSE is deprecated. Please use HANGUPCAUSE instead.\n");
|
||||
}
|
||||
} else if (!strcasecmp(v->name, "qualifygap")) {
|
||||
if (sscanf(v->value, "%30d", &global_qualify_gap) != 1) {
|
||||
ast_log(LOG_WARNING, "Invalid qualifygap '%s' at line %d of %s\n", v->value, v->lineno, config);
|
||||
|
||||
@@ -4828,6 +4828,8 @@ static int skinny_indicate(struct ast_channel *ast, int ind, const void *data, s
|
||||
break;
|
||||
default:
|
||||
ast_log(LOG_WARNING, "Don't know how to indicate condition %d\n", ind);
|
||||
/* fallthrough */
|
||||
case AST_CONTROL_PVT_CAUSE_CODE:
|
||||
return -1; /* Tell asterisk to provide inband signalling */
|
||||
}
|
||||
return 0;
|
||||
|
||||
@@ -5224,6 +5224,8 @@ static int unistim_indicate(struct ast_channel *ast, int ind, const void *data,
|
||||
break;
|
||||
default:
|
||||
ast_log(LOG_WARNING, "Don't know how to indicate condition %d\n", ind);
|
||||
/* fallthrough */
|
||||
case AST_CONTROL_PVT_CAUSE_CODE:
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
@@ -1714,6 +1714,9 @@ static int vpb_indicate(struct ast_channel *ast, int condition, const void *data
|
||||
case AST_CONTROL_UNHOLD:
|
||||
ast_moh_stop(ast);
|
||||
break;
|
||||
case AST_CONTROL_PVT_CAUSE_CODE:
|
||||
res = -1;
|
||||
break;
|
||||
default:
|
||||
res = 0;
|
||||
break;
|
||||
|
||||
@@ -1084,15 +1084,6 @@ srvlookup=yes ; Enable DNS SRV lookups on outbound calls
|
||||
|
||||
; jblog = no ; Enables jitterbuffer frame logging. Defaults to "no".
|
||||
|
||||
;----------------------------- SIP_CAUSE reporting ---------------------------------
|
||||
; storesipcause = no ; This option causes chan_sip to set the
|
||||
; HASH(SIP_CAUSE,<channel name>) channel variable
|
||||
; to the value of the last sip response.
|
||||
; WARNING: enabling this option carries a
|
||||
; significant performance burden. It should only
|
||||
; be used in low call volume situations. This
|
||||
; option defaults to "no".
|
||||
|
||||
;-----------------------------------------------------------------------------------
|
||||
|
||||
[authentication]
|
||||
|
||||
@@ -324,6 +324,9 @@ static void print_frame(struct ast_frame *frame)
|
||||
case AST_CONTROL_UPDATE_RTP_PEER:
|
||||
ast_verbose("SubClass: UPDATE_RTP_PEER\n");
|
||||
break;
|
||||
case AST_CONTROL_PVT_CAUSE_CODE:
|
||||
ast_verbose("SubClass: PVT_CAUSE_CODE\n");
|
||||
break;
|
||||
}
|
||||
|
||||
if (frame->subclass.integer == -1) {
|
||||
|
||||
@@ -266,6 +266,7 @@ enum ast_control_frame_type {
|
||||
AST_CONTROL_INCOMPLETE = 30, /*!< Indication that the extension dialed is incomplete */
|
||||
AST_CONTROL_MCID = 31, /*!< Indicate that the caller is being malicious. */
|
||||
AST_CONTROL_UPDATE_RTP_PEER = 32, /*!< Interrupt the bridge and have it update the peer */
|
||||
AST_CONTROL_PVT_CAUSE_CODE = 33, /*!< Contains an update to the protocol-specific cause-code stored for branching dials */
|
||||
};
|
||||
|
||||
enum ast_frame_read_action {
|
||||
@@ -324,6 +325,12 @@ enum ast_control_transfer {
|
||||
AST_TRANSFER_FAILED, /*!< Transfer request on the channel failed */
|
||||
};
|
||||
|
||||
struct ast_control_pvt_cause_code {
|
||||
char chan_name[AST_CHANNEL_NAME]; /*!< Name of the channel that originated the cause information */
|
||||
unsigned int emulate_sip_cause:1; /*!< Indicates whether this should be used to emulate SIP_CAUSE support */
|
||||
char code[1]; /*!< Tech-specific cause code information, beginning with the name of the tech */
|
||||
};
|
||||
|
||||
#define AST_SMOOTHER_FLAG_G729 (1 << 0)
|
||||
#define AST_SMOOTHER_FLAG_BE (1 << 1)
|
||||
|
||||
|
||||
@@ -3444,6 +3444,7 @@ int ast_waitfordigit_full(struct ast_channel *c, int ms, int audiofd, int cmdfd)
|
||||
ast_frfree(f);
|
||||
ast_clear_flag(ast_channel_flags(c), AST_FLAG_END_DTMF_ONLY);
|
||||
return -1;
|
||||
case AST_CONTROL_PVT_CAUSE_CODE:
|
||||
case AST_CONTROL_RINGING:
|
||||
case AST_CONTROL_ANSWER:
|
||||
case AST_CONTROL_SRCUPDATE:
|
||||
@@ -4171,6 +4172,7 @@ static int attribute_const is_visible_indication(enum ast_control_frame_type con
|
||||
case AST_CONTROL_END_OF_Q:
|
||||
case AST_CONTROL_MCID:
|
||||
case AST_CONTROL_UPDATE_RTP_PEER:
|
||||
case AST_CONTROL_PVT_CAUSE_CODE:
|
||||
break;
|
||||
|
||||
case AST_CONTROL_INCOMPLETE:
|
||||
@@ -4334,6 +4336,21 @@ int ast_indicate_data(struct ast_channel *chan, int _condition,
|
||||
case AST_CONTROL_CONGESTION:
|
||||
ts = ast_get_indication_tone(ast_channel_zone(chan), "congestion");
|
||||
break;
|
||||
case AST_CONTROL_PVT_CAUSE_CODE:
|
||||
{
|
||||
char causevar[256];
|
||||
const struct ast_control_pvt_cause_code *cause_code = data;
|
||||
|
||||
snprintf(causevar, sizeof(causevar), "HASH(HANGUPCAUSE,%s)", cause_code->chan_name);
|
||||
ast_func_write(chan, causevar, cause_code->code);
|
||||
if (cause_code->emulate_sip_cause) {
|
||||
snprintf(causevar, sizeof(causevar), "HASH(SIP_CAUSE,%s)", cause_code->chan_name);
|
||||
ast_func_write(chan, causevar, cause_code->code);
|
||||
}
|
||||
|
||||
res = 0;
|
||||
break;
|
||||
}
|
||||
case AST_CONTROL_PROGRESS:
|
||||
case AST_CONTROL_PROCEEDING:
|
||||
case AST_CONTROL_VIDUPDATE:
|
||||
@@ -5481,6 +5498,7 @@ struct ast_channel *__ast_request_and_dial(const char *type, struct ast_format_c
|
||||
break;
|
||||
|
||||
/* Ignore these */
|
||||
case AST_CONTROL_PVT_CAUSE_CODE:
|
||||
case AST_CONTROL_PROGRESS:
|
||||
case AST_CONTROL_PROCEEDING:
|
||||
case AST_CONTROL_HOLD:
|
||||
@@ -7172,6 +7190,7 @@ static enum ast_bridge_result ast_generic_bridge(struct ast_channel *c0, struct
|
||||
int bridge_exit = 0;
|
||||
|
||||
switch (f->subclass.integer) {
|
||||
case AST_CONTROL_PVT_CAUSE_CODE:
|
||||
case AST_CONTROL_AOC:
|
||||
case AST_CONTROL_MCID:
|
||||
ast_indicate_data(other, f->subclass.integer, f->data.ptr, f->datalen);
|
||||
|
||||
@@ -467,6 +467,9 @@ static void handle_frame(struct ast_dial *dial, struct ast_dial_channel *channel
|
||||
case AST_CONTROL_OFFHOOK:
|
||||
case AST_CONTROL_FLASH:
|
||||
break;
|
||||
case AST_CONTROL_PVT_CAUSE_CODE:
|
||||
ast_indicate_data(chan, AST_CONTROL_PVT_CAUSE_CODE, fr->data.ptr, fr->datalen);
|
||||
break;
|
||||
case -1:
|
||||
/* Prod the channel */
|
||||
ast_indicate(chan, -1);
|
||||
|
||||
@@ -3943,6 +3943,10 @@ static struct ast_channel *feature_request_and_dial(struct ast_channel *caller,
|
||||
ast_frfree(f);
|
||||
ready=1;
|
||||
break;
|
||||
} else if (f->subclass.integer == AST_CONTROL_PVT_CAUSE_CODE) {
|
||||
ast_indicate_data(caller, AST_CONTROL_PVT_CAUSE_CODE, f->data.ptr, f->datalen);
|
||||
ast_frfree(f);
|
||||
break;
|
||||
} else if (f->subclass.integer == AST_CONTROL_CONNECTED_LINE) {
|
||||
if (caller_hungup) {
|
||||
struct ast_party_connected_line connected;
|
||||
@@ -4463,6 +4467,7 @@ int ast_bridge_call(struct ast_channel *chan, struct ast_channel *peer, struct a
|
||||
ast_indicate_data(other, f->subclass.integer, f->data.ptr, f->datalen);
|
||||
}
|
||||
break;
|
||||
case AST_CONTROL_PVT_CAUSE_CODE:
|
||||
case AST_CONTROL_AOC:
|
||||
case AST_CONTROL_HOLD:
|
||||
case AST_CONTROL_UNHOLD:
|
||||
|
||||
@@ -1356,6 +1356,7 @@ static int waitstream_core(struct ast_channel *c, const char *breakon,
|
||||
case AST_CONTROL_REDIRECTING:
|
||||
case AST_CONTROL_AOC:
|
||||
case AST_CONTROL_UPDATE_RTP_PEER:
|
||||
case AST_CONTROL_PVT_CAUSE_CODE:
|
||||
case -1:
|
||||
/* Unimportant */
|
||||
break;
|
||||
|
||||
@@ -928,6 +928,9 @@ static enum ast_bridge_result local_bridge_loop(struct ast_channel *c0, struct a
|
||||
ast_indicate_data(other, fr->subclass.integer, fr->data.ptr, fr->datalen);
|
||||
}
|
||||
ast_frfree(fr);
|
||||
} else if (fr->subclass.integer == AST_CONTROL_PVT_CAUSE_CODE) {
|
||||
ast_indicate_data(other, fr->subclass.integer, fr->data.ptr, fr->datalen);
|
||||
ast_frfree(fr);
|
||||
} else {
|
||||
*fo = fr;
|
||||
*rc = who;
|
||||
@@ -1219,6 +1222,9 @@ static enum ast_bridge_result remote_bridge_loop(struct ast_channel *c0,
|
||||
ast_indicate_data(other, fr->subclass.integer, fr->data.ptr, fr->datalen);
|
||||
}
|
||||
ast_frfree(fr);
|
||||
} else if (fr->subclass.integer == AST_CONTROL_PVT_CAUSE_CODE) {
|
||||
ast_indicate_data(other, fr->subclass.integer, fr->data.ptr, fr->datalen);
|
||||
ast_frfree(fr);
|
||||
} else {
|
||||
*fo = fr;
|
||||
*rc = who;
|
||||
|
||||
Reference in New Issue
Block a user