mirror of
https://github.com/asterisk/asterisk.git
synced 2025-10-26 14:27:14 +00:00
func_hangupcause.c: Add access to Reason headers via HANGUPCAUSE()
As soon as SIP call may end with several Reason headers, we want to make all of them available through the HAGUPCAUSE() function. This implementation uses the same ao2 hash for cause codes storage and adds a flag to make difference between last processed sip message and content of reason headers. UserNote: Added a new option to HANGUPCAUSE to access additional information about hangup reason. Reason headers from pjsip could be read using 'tech_extended' cause type.
This commit is contained in:
@@ -55,6 +55,7 @@
|
||||
<para>Parameter describing which type of information is requested. Types are:</para>
|
||||
<enumlist>
|
||||
<enum name="tech"><para>Technology-specific cause information</para></enum>
|
||||
<enum name="tech_extended"><para>Technology-specific extended list of cause information</para></enum>
|
||||
<enum name="ast"><para>Translated Asterisk cause code</para></enum>
|
||||
</enumlist>
|
||||
</parameter>
|
||||
@@ -119,9 +120,10 @@ static int hangupcause_read(struct ast_channel *chan, const char *cmd, char *dat
|
||||
char *parms;
|
||||
struct ast_control_pvt_cause_code *cause_code;
|
||||
int res = 0;
|
||||
struct ast_str *causelist;
|
||||
AST_DECLARE_APP_ARGS(args,
|
||||
AST_APP_ARG(channel); /*!< Channel name */
|
||||
AST_APP_ARG(type); /*!< Type of information requested (ast or tech) */
|
||||
AST_APP_ARG(type); /*!< Type of information requested (ast, tech or tech_extended) */
|
||||
);
|
||||
|
||||
/* Ensure that the buffer is empty */
|
||||
@@ -139,25 +141,49 @@ static int hangupcause_read(struct ast_channel *chan, const char *cmd, char *dat
|
||||
return -1;
|
||||
}
|
||||
|
||||
ast_channel_lock(chan);
|
||||
cause_code = ast_channel_dialed_causes_find(chan, args.channel);
|
||||
ast_channel_unlock(chan);
|
||||
|
||||
if (!cause_code) {
|
||||
ast_log(LOG_WARNING, "Unable to find information for channel %s\n", args.channel);
|
||||
causelist = ast_str_create(128);
|
||||
if (!causelist) {
|
||||
ast_log(LOG_ERROR, "Unable to allocate buffer, cause information will be unavailable!\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
ast_channel_lock(chan);
|
||||
if (!strcmp(args.type, "tech_extended")) {
|
||||
struct ao2_iterator *cause_codes;
|
||||
cause_codes = ast_channel_dialed_causes_find_multiple(chan, args.channel);
|
||||
while ((cause_code = ao2_iterator_next(cause_codes))) {
|
||||
if (!cause_code->cause_extended) {
|
||||
ao2_ref(cause_code, -1);
|
||||
continue;
|
||||
}
|
||||
ast_str_append(&causelist, 0, "%s%s", (ast_str_strlen(causelist) ? "," : ""), cause_code->code);
|
||||
ao2_ref(cause_code, -1);
|
||||
}
|
||||
ao2_iterator_destroy(cause_codes);
|
||||
} else {
|
||||
cause_code = ast_channel_dialed_causes_find(chan, args.channel);
|
||||
if (!cause_code) {
|
||||
ast_log(LOG_WARNING, "Unable to find information for channel '%s'\n", args.channel);
|
||||
ast_channel_unlock(chan);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
ast_channel_unlock(chan);
|
||||
|
||||
if (!strcmp(args.type, "ast")) {
|
||||
ast_copy_string(buf, ast_cause2str(cause_code->ast_cause), len);
|
||||
} else if (!strcmp(args.type, "tech")) {
|
||||
ast_copy_string(buf, cause_code->code, len);
|
||||
} else if (!strcmp(args.type, "tech_extended")) {
|
||||
ast_copy_string(buf, ast_str_buffer(causelist), len);
|
||||
} else {
|
||||
ast_log(LOG_WARNING, "Information type not recognized (%s)\n", args.type);
|
||||
res = -1;
|
||||
}
|
||||
|
||||
ao2_ref(cause_code, -1);
|
||||
if (cause_code) {
|
||||
ao2_cleanup(cause_code);
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user