mirror of
https://github.com/asterisk/asterisk.git
synced 2025-10-18 02:32:36 +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:
@@ -1145,23 +1145,68 @@ struct ast_str *ast_channel_dialed_causes_channels(const struct ast_channel *cha
|
||||
|
||||
struct ast_control_pvt_cause_code *ast_channel_dialed_causes_find(const struct ast_channel *chan, const char *chan_name)
|
||||
{
|
||||
return ao2_find(chan->dialed_causes, chan_name, OBJ_KEY);
|
||||
struct ao2_iterator causes;
|
||||
struct ast_control_pvt_cause_code *cause_code;
|
||||
|
||||
causes = ao2_iterator_init(chan->dialed_causes, 0);
|
||||
while ((cause_code = ao2_iterator_next(&causes))) {
|
||||
if (strcmp(cause_code->chan_name, chan_name)) {
|
||||
ao2_ref(cause_code, -1);
|
||||
continue;
|
||||
}
|
||||
if (!cause_code->cause_extended) {
|
||||
ao2_iterator_destroy(&causes);
|
||||
return cause_code;
|
||||
}
|
||||
ao2_ref(cause_code, -1);
|
||||
}
|
||||
ao2_iterator_destroy(&causes);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
struct ao2_iterator *ast_channel_dialed_causes_find_multiple(const struct ast_channel *chan, const char *chan_name)
|
||||
{
|
||||
struct ao2_iterator *causes;
|
||||
struct ast_control_pvt_cause_code *cause_code;
|
||||
|
||||
causes = ao2_find(chan->dialed_causes, chan_name, OBJ_SEARCH_KEY | OBJ_MULTIPLE);
|
||||
while ((cause_code = ao2_iterator_next(causes))) {
|
||||
ao2_ref(cause_code, -1);
|
||||
}
|
||||
ao2_iterator_destroy(causes);
|
||||
|
||||
return ao2_find(chan->dialed_causes, chan_name, OBJ_SEARCH_KEY | OBJ_MULTIPLE);
|
||||
}
|
||||
|
||||
static int remove_dialstatus_cb(void *obj, void *arg, int flags)
|
||||
{
|
||||
struct ast_control_pvt_cause_code *cause_code = obj;
|
||||
char *str = ast_tech_to_upper(ast_strdupa(arg));
|
||||
char *pc_str = ast_tech_to_upper(ast_strdupa(cause_code->chan_name));
|
||||
|
||||
if (cause_code->cause_extended) {
|
||||
return 0;
|
||||
}
|
||||
return !strcmp(pc_str, str) ? CMP_MATCH | CMP_STOP : 0;
|
||||
}
|
||||
|
||||
int ast_channel_dialed_causes_add(const struct ast_channel *chan, const struct ast_control_pvt_cause_code *cause_code, int datalen)
|
||||
{
|
||||
struct ast_control_pvt_cause_code *ao2_cause_code;
|
||||
ao2_find(chan->dialed_causes, cause_code->chan_name, OBJ_KEY | OBJ_UNLINK | OBJ_NODATA);
|
||||
ao2_cause_code = ao2_alloc(datalen, NULL);
|
||||
char *arg = ast_strdupa(cause_code->chan_name);
|
||||
|
||||
ao2_callback(chan->dialed_causes, OBJ_MULTIPLE | OBJ_NODATA | OBJ_UNLINK, remove_dialstatus_cb, arg);
|
||||
|
||||
ao2_cause_code = ao2_alloc(datalen, NULL);
|
||||
if (ao2_cause_code) {
|
||||
memcpy(ao2_cause_code, cause_code, datalen);
|
||||
ao2_link(chan->dialed_causes, ao2_cause_code);
|
||||
ao2_ref(ao2_cause_code, -1);
|
||||
return 0;
|
||||
} else {
|
||||
return -1;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
void ast_channel_dialed_causes_clear(const struct ast_channel *chan)
|
||||
|
Reference in New Issue
Block a user